Parcourir la source

广告维度的聚合完成

wcc il y a 3 ans
Parent
commit
ebc3e1cef4
17 fichiers modifiés avec 5080 ajouts et 268 suppressions
  1. 1 1
      flink-ad-monitoring/dependency-reduced-pom.xml
  2. 1 1
      flink-ad-monitoring/pom.xml
  3. 193 80
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/AdStatJob.java
  4. 1 1
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/BatchJob.java
  5. 574 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/PlanStatJob.java
  6. 14 8
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/Test.java
  7. 1 1
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdDataOfHourODS.java
  8. 0 87
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfDayDWD.java
  9. 73 73
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfHourDWD.java
  10. 765 3
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfMinuteDWD.java
  11. 1498 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/PlanStatOfDayDWD.java
  12. 1888 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/PlanStatOfHourDWD.java
  13. 10 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/util/DateUtil.java
  14. 48 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/util/PlanUtil.java
  15. 2 2
      flink-ad-monitoring/src/main/resources/ad_stream_of_day.properties
  16. 2 2
      flink-ad-monitoring/src/main/resources/ad_stream_of_minute.properties
  17. 9 9
      flink-ad-monitoring/src/main/resources/application.properties

+ 1 - 1
flink-ad-monitoring/dependency-reduced-pom.xml

@@ -88,7 +88,7 @@
               </filters>
               <transformers>
                 <transformer>
-                  <mainClass>flink.zanxiangnet.ad.monitoring.KafkaDemoJob</mainClass>
+                  <mainClass>flink.zanxiangnet.ad.monitoring.AdStatJob</mainClass>
                 </transformer>
               </transformers>
             </configuration>

+ 1 - 1
flink-ad-monitoring/pom.xml

@@ -202,7 +202,7 @@ under the License.
                             <transformers>
                                 <transformer
                                         implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
-                                    <mainClass>flink.zanxiangnet.ad.monitoring.KafkaDemoJob</mainClass>
+                                    <mainClass>flink.zanxiangnet.ad.monitoring.AdStatJob</mainClass>
                                 </transformer>
                             </transformers>
                         </configuration>

+ 193 - 80
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/KafkaDemoJob.java → flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/AdStatJob.java

@@ -11,7 +11,6 @@ import com.tencent.ads.model.HourlyReportsGetListStruct;
 import flink.zanxiangnet.ad.monitoring.maxcompute.MaxComputeLog;
 import flink.zanxiangnet.ad.monitoring.maxcompute.sink.TunnelBatchSink;
 import flink.zanxiangnet.ad.monitoring.pojo.dto.AdDataOfDayDTO;
-import flink.zanxiangnet.ad.monitoring.pojo.dto.AdStatOfDayDWDDTO;
 import flink.zanxiangnet.ad.monitoring.pojo.dto.AdStatOfDayODSDTO;
 import flink.zanxiangnet.ad.monitoring.pojo.entity.*;
 import flink.zanxiangnet.ad.monitoring.pojo.properties.ApplicationProperties;
@@ -21,20 +20,13 @@ import flink.zanxiangnet.ad.monitoring.util.DateUtil;
 import flink.zanxiangnet.ad.monitoring.util.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.flink.api.common.eventtime.*;
-import org.apache.flink.api.common.functions.MapFunction;
-import org.apache.flink.api.common.functions.RichMapFunction;
-import org.apache.flink.api.common.functions.RichReduceFunction;
 import org.apache.flink.api.common.serialization.SimpleStringSchema;
-import org.apache.flink.api.connector.sink.Sink;
-import org.apache.flink.api.java.DataSet;
-import org.apache.flink.api.java.ExecutionEnvironment;
 import org.apache.flink.api.java.functions.KeySelector;
 import org.apache.flink.configuration.Configuration;
 import org.apache.flink.connector.kafka.source.KafkaSource;
 import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
 import org.apache.flink.streaming.api.datastream.DataStream;
 import org.apache.flink.streaming.api.datastream.DataStreamSource;
-import org.apache.flink.streaming.api.datastream.KeyedStream;
 import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
 import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
 import org.apache.flink.streaming.api.functions.ProcessFunction;
@@ -42,6 +34,7 @@ import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
 import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
 import org.apache.flink.streaming.api.windowing.time.Time;
 import org.apache.flink.streaming.api.windowing.windows.GlobalWindow;
+import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
 import org.apache.flink.util.Collector;
 import org.apache.flink.util.OutputTag;
 import org.apache.kafka.clients.CommonClientConfigs;
@@ -55,11 +48,11 @@ import org.springframework.beans.BeanUtils;
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.LocalTime;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
 
-public class KafkaDemoJob {
+public class AdStatJob {
 
     /**
      * 可能有数据的最早日期
@@ -67,14 +60,14 @@ public class KafkaDemoJob {
     private static final String OLDEST_DAY = "2019-01-01";
 
     public static void main(String[] args) throws Exception {
-        // System.setProperty("javax.net.ssl.trustStore", "D:\\Downloads\\kafka.client.truststore.jks");
-        System.setProperty("javax.net.ssl.trustStore", "/root/flink-1.13.2/kafka.client.truststore.jks");
+        System.setProperty("javax.net.ssl.trustStore", "D:\\Downloads\\kafka.client.truststore.jks");
+        // System.setProperty("javax.net.ssl.trustStore", "/root/flink-1.13.2/kafka.client.truststore.jks");
         System.setProperty("javax.net.ssl.trustStorePassword", "KafkaOnsClient");
         StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
 
         // 加载配置文件到 flink的全局配置中
         Properties props = new Properties();
-        props.load(KafkaDemoJob.class.getResourceAsStream("/application.properties"));
+        props.load(AdStatJob.class.getResourceAsStream("/application.properties"));
         Configuration configuration = new Configuration();
         props.stringPropertyNames().forEach(key -> {
             String value = props.getProperty(key);
@@ -83,7 +76,7 @@ public class KafkaDemoJob {
         env.getConfig().setGlobalJobParameters(configuration);
 
         Properties adStreamOfMinuteProps = new Properties();
-        adStreamOfMinuteProps.load(KafkaDemoJob.class.getResourceAsStream("/ad_stream_of_minute.properties"));
+        adStreamOfMinuteProps.load(AdStatJob.class.getResourceAsStream("/ad_stream_of_minute.properties"));
         KafkaSource<String> adStreamOfMinuteSource = buildKafkaSource(adStreamOfMinuteProps);
 
         DataStreamSource<String> adStreamOfMinuteIn = env.fromSource(adStreamOfMinuteSource, WatermarkStrategy.noWatermarks(), "adStreamOfMinuteSource_kafka");
@@ -96,7 +89,7 @@ public class KafkaDemoJob {
         };
 
         // 对流进行映射,拆分(实时的分钟流和回滚的小时流)
-        SingleOutputStreamOperator<AdDataOfMinuteODS> adOdsStream = adStreamOfMinuteIn.filter(StringUtils::isNotBlank)
+        SingleOutputStreamOperator<AdDataOfMinuteODS> adODSStream = adStreamOfMinuteIn.filter(StringUtils::isNotBlank)
                 .process(new ProcessFunction<String, AdDataOfMinuteODS>() {
                     @Override
                     public void processElement(String adDataStr, ProcessFunction<String, AdDataOfMinuteODS>.Context context, Collector<AdDataOfMinuteODS> collector) throws Exception {
@@ -104,51 +97,162 @@ public class KafkaDemoJob {
                         // 指记录被创建的时间
                         long createTime = dto.getCreateTime();
                         // 指记录统计的时间(如果是实时统计的数据精确到分钟,回滚的历史数据精确到天)
-                        long statTime = dto.getDataTime() == null ? createTime : dto.getDataTime();
+                        long statTime = DateUtil.localDateTimeToMilli(DateUtil.milliToLocalDateTime(dto.getDataTime()).withSecond(0).withNano(0));
                         HourlyReportsGetListStruct struct = dto.getHourlyReportsGetListStruct();
 
                         if (createTime - statTime > (60 * 60 * 1000L)) {
-                            AdDataOfHourODS adOds = new AdDataOfHourODS();
-                            BeanUtils.copyProperties(struct, adOds);
-                            adOds.setStatDay(DateUtil.formatLocalDate(DateUtil.milliToLocalDate(statTime)));
-                            adOds.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
-                            adOds.setStatTime(statTime);
-                            adOds.setAccountId(dto.getAccountId());
-                            adOds.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
-                            adOds.setCreateTime(new Date(createTime));
-                            context.output(adHourStreamTag, adOds);
+                            AdDataOfHourODS adODS = new AdDataOfHourODS();
+                            BeanUtils.copyProperties(struct, adODS);
+                            adODS.setStatDay(DateUtil.formatLocalDate(DateUtil.milliToLocalDate(statTime)));
+                            adODS.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
+                            adODS.setStatTime(DateUtil.localDateTimeToMilli(DateUtil.milliToLocalDateTime(statTime).withMinute(0)));
+                            adODS.setAccountId(dto.getAccountId());
+                            adODS.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
+                            adODS.setCreateTime(new Date(createTime));
+                            context.output(adHourStreamTag, adODS);
                         } else {
-                            AdDataOfMinuteODS adOds = new AdDataOfMinuteODS();
-                            BeanUtils.copyProperties(struct, adOds);
-                            adOds.setStatDay(DateUtil.formatLocalDate(DateUtil.milliToLocalDate(statTime)));
-                            adOds.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
-                            adOds.setStatTime(statTime);
-                            adOds.setAccountId(dto.getAccountId());
-                            adOds.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
-                            adOds.setCreateTime(new Date(createTime));
-                            context.output(adMinuteStreamTag, adOds);
+                            AdDataOfMinuteODS adODS = new AdDataOfMinuteODS();
+                            BeanUtils.copyProperties(struct, adODS);
+                            adODS.setStatDay(DateUtil.formatLocalDate(DateUtil.milliToLocalDate(statTime)));
+                            adODS.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
+                            adODS.setStatTime(statTime);
+                            adODS.setAccountId(dto.getAccountId());
+                            adODS.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
+                            adODS.setCreateTime(new Date(createTime));
+                            context.output(adMinuteStreamTag, adODS);
                         }
                     }
                 });
 
         // 分钟流
-        SingleOutputStreamOperator<AdDataOfMinuteODS> adMinuteOdsStream = adOdsStream.getSideOutput(adMinuteStreamTag)
-                // 打水印,允许延迟 60分钟,同时指定时间流
-                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfMinuteODS>forBoundedOutOfOrderness(Duration.ofMinutes(60L))
-                        .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfMinuteODS>) (adOds, l) -> adOds.getStatTime())
-                );
+        DataStream<AdDataOfMinuteODS> adMinuteODSStream = adODSStream.getSideOutput(adMinuteStreamTag);
         // 写入原始表
-        adMinuteOdsStream.addSink(new TunnelBatchSink<>(AdDataOfMinuteODS.class, 36000L, 64000L, 3));
+        adMinuteODSStream.addSink(new TunnelBatchSink<>(AdDataOfMinuteODS.class, 36000L, 64000L, 3));
+        adMinuteODSStream
+                // 打水印,允许数据延迟 6分钟,同时指定时间流
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfMinuteODS>forBoundedOutOfOrderness(Duration.ofMinutes(6L))
+                        .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfMinuteODS>) (adODS, l) -> adODS.getStatTime()))
+                .keyBy(AdDataOfMinuteODS::getAdId)
+                // 开一个 5分钟的滚动窗口
+                .window(TumblingEventTimeWindows.of(Time.minutes(5L)))
+                .process(new ProcessWindowFunction<AdDataOfMinuteODS, AdStatOfMinuteDWD, Long, TimeWindow>() {
+                    // 对象锁,防止MaxCompute的 Tunnel对象多次初始化
+                    private final String DUMMY_LOCK = "DUMMY_LOCK";
+                    private Odps odps;
+                    private long lastClearTime = System.currentTimeMillis();
+                    private final Map<Long, String> lastAdDayQueryDay = new ConcurrentHashMap<>();
+                    // 历史的天数据
+                    private final Map<Long, AdStatOfDayDWD> historyDayData = new ConcurrentHashMap<>();
+                    // 之前聚合的昨天的数据
+                    private final Map<Long, Map<String, AdStatOfMinuteDWD>> historyMinuteData = new ConcurrentHashMap<>();
+                    // 前 5分钟聚合的数据
+                    private final Map<Long, Map<String, AdStatOfMinuteDWD>> lastReduceData = new ConcurrentHashMap<>();
+
+                    private void clearData() {
+                        lastAdDayQueryDay.entrySet().removeIf(entry -> DateUtil.parseLocalDate(entry.getValue()).compareTo(LocalDate.now().minusDays(3L)) <= 0);
+                        historyDayData.entrySet().removeIf(entry -> DateUtil.parseLocalDate(entry.getValue().getStatDay()).compareTo(LocalDate.now().minusDays(50L)) <= 0);
+                        historyMinuteData.forEach((key, value) -> {
+                            if (value != null) {
+                                value.entrySet().removeIf(entry2 -> DateUtil.parseLocalDate(entry2.getKey()).compareTo(LocalDate.now().minusDays(3L)) <= 0);
+                            }
+                        });
+                        historyMinuteData.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().isEmpty());
+
+                        lastReduceData.forEach((key, value) -> {
+                            if (value != null) {
+                                value.entrySet().removeIf(entry -> DateUtil.parseOfMinuteReduce(entry.getKey()).compareTo(LocalDateTime.now().minusHours(1)) <= 0);
+                            }
+                        });
+                        lastReduceData.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().isEmpty());
+                    }
+
+                    @Override
+                    public void open(Configuration conf) {
+                        Map<String, String> params = getRuntimeContext()
+                                .getExecutionConfig()
+                                .getGlobalJobParameters()
+                                .toMap();
+                        Account account = new AliyunAccount(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ID),
+                                params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_KEY));
+                        odps = new Odps(account);
+                        odps.getRestClient().setRetryLogger(new MaxComputeLog());
+                        odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
+                        odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
+                    }
+
+                    @Override
+                    public void process(Long elementCount, ProcessWindowFunction<AdDataOfMinuteODS, AdStatOfMinuteDWD, Long, TimeWindow>.Context context,
+                                        Iterable<AdDataOfMinuteODS> iterable, Collector<AdStatOfMinuteDWD> collector) throws Exception {
+                        LocalDateTime beginTime = DateUtil.milliToLocalDateTime(context.window().getStart());
+                        String statDay = DateUtil.formatLocalDate(beginTime.toLocalDate());
+                        String reduceTimeKey = DateUtil.formatOfMinuteReduce(beginTime);
+                        int hour = beginTime.getHour();
+                        long now = System.currentTimeMillis();
+                        AdDataOfMinuteODS statODS = null;
+                        List<AdDataOfMinuteODS> adDataOfMinuteODSList = new ArrayList<>(24);
+                        for (AdDataOfMinuteODS adDataOfMinuteODS : iterable) {
+                            adDataOfMinuteODSList.add(adDataOfMinuteODS);
+                            if (adDataOfMinuteODS.getHour() != hour) {
+                                continue;
+                            }
+                            statODS = adDataOfMinuteODS;
+                            break;
+                        }
+                        if (statODS == null) {
+                            return;
+                        }
+
+                        // 每 12小时清理一次数据
+                        if (now - lastClearTime > 12 * 60 * 60 * 1000) {
+                            synchronized (DUMMY_LOCK) {
+                                if (now - lastClearTime > 12 * 60 * 60 * 1000) {
+                                    clearData();
+                                    lastClearTime = now;
+                                }
+                            }
+                        }
+                        Long adId = statODS.getAdId();
+
+                        // 昨天聚合的数据
+                        Map<String, AdStatOfMinuteDWD> historyMinuteMapping = historyMinuteData.computeIfAbsent(adId, key -> new HashMap<>());
+                        AdStatOfMinuteDWD yesterdayMinuteDWD = historyMinuteMapping.get(DateUtil.formatLocalDate(beginTime.minusDays(1L).toLocalDate()));
+                        // 之前的数据
+                        String lastQueryDay = lastAdDayQueryDay.get(adId);
+                        if (lastQueryDay == null || !lastQueryDay.equals(statDay)) {
+                            // 往前找 30天
+                            LocalDate endDay = beginTime.minusDays(2L).toLocalDate(), beginDay = endDay.minusDays(30L);
+                            Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_day_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginDay) + "\" AND stat_day <= \"" + endDay + "\" AND ad_id = " + adId + ";");
+                            instance.waitForSuccess();
+                            List<Record> records = SQLTask.getResult(instance);
+                            List<AdStatOfDayDWD> temp = records.stream().map(AdStatOfDayDWD::byMaxCompute).sorted((val1, val2) -> {
+                                if (val1.getStatDay().equals(val2.getStatDay())) {
+                                    return new Long(val1.getCreateTime().getTime() - val2.getCreateTime().getTime()).intValue();
+                                }
+                                return DateUtil.parseLocalDate(val1.getStatDay()).compareTo(DateUtil.parseLocalDate(val2.getStatDay()));
+                            }).collect(Collectors.toList());
+                            historyDayData.put(adId, temp.isEmpty() ? null : temp.get(temp.size() - 1));
+                            lastAdDayQueryDay.put(adId, statDay);
+                        }
+                        AdStatOfDayDWD beforeYesterdayDayDWD = historyDayData.get(adId);
+                        Map<String, AdStatOfMinuteDWD> lastReduceMapping = lastReduceData.computeIfAbsent(adId, key -> new HashMap<>());
+                        // 聚合当天的全部数据
+                        AdStatOfMinuteDWD nowAdStat = AdStatOfMinuteDWD.reduce(beforeYesterdayDayDWD, yesterdayMinuteDWD, adDataOfMinuteODSList, statODS, lastReduceMapping.get(DateUtil.formatOfMinuteReduce(beginTime.minusMinutes(5L))), now);
+                        collector.collect(nowAdStat);
+                        lastReduceMapping.put(reduceTimeKey, nowAdStat);
+                        historyMinuteMapping.put(statDay, nowAdStat);
+                    }
+                }).addSink(new TunnelBatchSink<>(AdStatOfMinuteDWD.class, 30000L, 365L, 6));
+        ;
 
         // 小时流(直接写到小时报表的 ods)
-        DataStream<AdDataOfHourODS> adHourOdsStream = adOdsStream.getSideOutput(adHourStreamTag);
+        DataStream<AdDataOfHourODS> adHourODSStream = adODSStream.getSideOutput(adHourStreamTag);
         // 写入原始表
-        adHourOdsStream.addSink(new TunnelBatchSink<>(AdDataOfHourODS.class, 36000L, 64000L, 10));
-        adHourOdsStream.keyBy(AdDataOfHourODS::getAdId)
+        adHourODSStream.addSink(new TunnelBatchSink<>(AdDataOfHourODS.class, 36000L, 64000L, 10));
+        adHourODSStream.keyBy(AdDataOfHourODS::getAdId)
                 .countWindow(1).process(new ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>() {
                     private Odps odps;
-                    private long lastQueryTime = System.currentTimeMillis();
-                    private Map<String, Map<Integer, AdStatOfHourDWD>> historyData;
+                    private final Map<Long, Long> lastAdQueryTime = new ConcurrentHashMap<>();
+                    private final Map<Long, Map<String, Map<Integer, AdStatOfHourDWD>>> historyAdData = new ConcurrentHashMap<>();
 
                     @Override
                     public void open(Configuration conf) {
@@ -168,10 +272,14 @@ public class KafkaDemoJob {
                     public void process(Long elementsCount, ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfHourODS> iterable, Collector<AdStatOfHourDWD> collector) throws Exception {
                         AdDataOfHourODS element = iterable.iterator().next();
                         LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
-                        int hour = element.getHour();
+                        Integer hour = element.getHour();
                         long now = System.currentTimeMillis();
-                        // 拉取指定 key的数据
-                        if (historyData == null || (now - lastQueryTime) > 60 * 60 * 1000) {
+                        Long adId = element.getAdId();
+
+                        Map<String, Map<Integer, AdStatOfHourDWD>> historyData = historyAdData.computeIfAbsent(adId, key -> new HashMap<>());
+                        Long lastQueryTime = lastAdQueryTime.get(adId);
+                        // 从 maxCompute拉取指定 广告的历史数据
+                        if (lastQueryTime == null || (now - lastQueryTime) > 3 * 60 * 60 * 1000) {
                             LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(40);
                             Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_hour_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
                             instance.waitForSuccess();
@@ -180,16 +288,15 @@ public class KafkaDemoJob {
                                     .map(AdStatOfHourDWD::byMaxCompute)
                                     .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue())
                                     .collect(Collectors.toList());
-                            historyData = new HashMap<>();
                             for (AdStatOfHourDWD adStatOfHourDWD : historyList) {
                                 Map<Integer, AdStatOfHourDWD> hourMapping = historyData.computeIfAbsent(adStatOfHourDWD.getStatDay(), key -> new HashMap<>());
                                 hourMapping.put(adStatOfHourDWD.getHour(), adStatOfHourDWD);
                             }
-                            lastQueryTime = now;
+                            lastAdQueryTime.put(adId, now);
                         }
                         // 找到这个号当天内上个小时统计的数据
                         AdStatOfHourDWD lastHourData = null;
-                        // 往前查 40天,找到上一条数据
+                        // 往前查 40天,找到广告上一次聚合的数据
                         for (int i = 0; i < 40; i++) {
                             Map<Integer, AdStatOfHourDWD> mapData = historyData.get(DateUtil.formatLocalDate(statDay.minusDays(i)));
                             if (mapData == null || mapData.isEmpty()) {
@@ -216,7 +323,7 @@ public class KafkaDemoJob {
                 }).addSink(new TunnelBatchSink<>(AdStatOfHourDWD.class, 30000L, 365L, 6));
 
         // 获取指定广告的历史统计信息(用于统计总的消耗信息等)
-        /*SingleOutputStreamOperator<AdStatOfHourDWD> adHourDWDStream = adHourOdsStream.map(AdStatOfHourDWD::byODS)
+        /*SingleOutputStreamOperator<AdStatOfHourDWD> adHourDWDStream = adHourODSStream.map(AdStatOfHourDWD::byODS)
                 .keyBy((KeySelector<AdStatOfHourDWD, String>) adHourDWD -> adHourDWD.getStatDay() + "_" + adHourDWD.getAdId())
                 // 开一个按天滚动的窗口
                 .window(TumblingEventTimeWindows.of(Time.days(1L)))
@@ -255,7 +362,7 @@ public class KafkaDemoJob {
 
         // ------------------------------------------------------- 处理广告的天数据 -----------------------------------------
         Properties adStreamOfDayProps = new Properties();
-        adStreamOfDayProps.load(KafkaDemoJob.class.getResourceAsStream("/ad_stream_of_day.properties"));
+        adStreamOfDayProps.load(AdStatJob.class.getResourceAsStream("/ad_stream_of_day.properties"));
         KafkaSource<String> adStreamOfDaySource = buildKafkaSource(adStreamOfDayProps);
 
         DataStreamSource<String> adStreamOfDayIn = env.fromSource(adStreamOfDaySource, WatermarkStrategy.noWatermarks(), "adStreamOfMinuteSource_kafka");
@@ -266,55 +373,55 @@ public class KafkaDemoJob {
         // 广告日数据。往前回滚 1年
         final OutputTag<AdDataOfDayODS> adDayStreamRollYearTag = new OutputTag<AdDataOfDayODS>("adDayStreamRollYearTag") {
         };
-        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayOdsStream = adStreamOfDayIn.filter(StringUtils::isNotBlank)
+        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayODSStream = adStreamOfDayIn.filter(StringUtils::isNotBlank)
                 .map(str -> {
                     AdDataOfDayDTO dto = JsonUtil.toObj(str, AdDataOfDayDTO.class);
                     Date createTime = new Date(dto.getCreateTime());
                     DailyReportsGetListStruct struct = dto.getDailyReportsGetListStruct();
-                    AdDataOfDayODS adOds = new AdDataOfDayODS();
-                    BeanUtils.copyProperties(struct, adOds);
-                    adOds.setStatDay(struct.getDate());
-                    adOds.setAccountId(dto.getAccountId());
-                    adOds.setCampaignId(struct.getCampaignId());
-                    adOds.setAgencyAccountId(struct.getAccountId());
-                    adOds.setWechatAccountId(struct.getWechatAccountId());
-                    adOds.setAdgroupId(struct.getAdgroupId());
-                    adOds.setAdId(struct.getAdId());
-                    adOds.setCreateTime(createTime);
+                    AdDataOfDayODS adODS = new AdDataOfDayODS();
+                    BeanUtils.copyProperties(struct, adODS);
+                    adODS.setStatDay(struct.getDate());
+                    adODS.setAccountId(dto.getAccountId());
+                    adODS.setCampaignId(struct.getCampaignId());
+                    adODS.setAgencyAccountId(struct.getAccountId());
+                    adODS.setWechatAccountId(struct.getWechatAccountId());
+                    adODS.setAdgroupId(struct.getAdgroupId());
+                    adODS.setAdId(struct.getAdId());
+                    adODS.setCreateTime(createTime);
                     return AdStatOfDayODSDTO.builder()
                             .startDate(dto.getStartDate())
                             .endDate(dto.getEndDate())
-                            .adDataOfDayODS(adOds)
+                            .adDataOfDayODS(adODS)
                             .build();
                 });
-        adDayOdsStream.map(AdStatOfDayODSDTO::getAdDataOfDayODS).addSink(new TunnelBatchSink<>(AdDataOfDayODS.class, 36000L, 6000L, 10));
+        adDayODSStream.map(AdStatOfDayODSDTO::getAdDataOfDayODS).addSink(new TunnelBatchSink<>(AdDataOfDayODS.class, 36000L, 6000L, 10));
 
         // 拆分流
-        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayOdsStreamSplit = adDayOdsStream.process(new ProcessFunction<AdStatOfDayODSDTO, AdStatOfDayODSDTO>() {
+        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayODSStreamSplit = adDayODSStream.process(new ProcessFunction<AdStatOfDayODSDTO, AdStatOfDayODSDTO>() {
             @Override
             public void processElement(AdStatOfDayODSDTO adDataDTO, ProcessFunction<AdStatOfDayODSDTO, AdStatOfDayODSDTO>.Context context, Collector<AdStatOfDayODSDTO> collector) throws Exception {
                 LocalDate startDate = adDataDTO.getStartDate();
                 LocalDate endDate = adDataDTO.getEndDate();
-                AdDataOfDayODS adOds = adDataDTO.getAdDataOfDayODS();
+                AdDataOfDayODS adODS = adDataDTO.getAdDataOfDayODS();
                 if (DateUtil.intervalOfDays(startDate, endDate) > 31L) {
                     // 拉取时间间隔超过 1个月,账号回滚 365天的数据
-                    context.output(adDayStreamRollYearTag, adOds);
+                    context.output(adDayStreamRollYearTag, adODS);
                 } else {
                     // 每日往前回滚 10天的数据
-                    context.output(adDayStreamRollDayTag, adOds);
+                    context.output(adDayStreamRollDayTag, adODS);
                 }
             }
         });
 
-        adDayOdsStreamSplit.getSideOutput(adDayStreamRollDayTag)
+        adDayODSStreamSplit.getSideOutput(adDayStreamRollDayTag)
                 // 打水印,允许延迟 10天(应为允许回滚 10天),同时指定事件时间
                 .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfDayODS>forBoundedOutOfOrderness(Duration.ofDays(10L))
                         .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfDayODS>) (adDay, l) -> DateUtil.localDateToMilli(DateUtil.parseLocalDate(adDay.getStatDay())))
                 ).keyBy(AdDataOfDayODS::getAdId)
                 .countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
                     private Odps odps;
-                    private long lastQueryTime = System.currentTimeMillis();
-                    private Map<String, AdStatOfDayDWD> historyData;
+                    private final Map<Long, Long> lastAdQueryTime = new ConcurrentHashMap<>();
+                    private final Map<Long, Map<String, AdStatOfDayDWD>> historyAdData = new ConcurrentHashMap<>();
 
                     @Override
                     public void open(Configuration conf) {
@@ -333,19 +440,25 @@ public class KafkaDemoJob {
                     @Override
                     public void process(Long elementsCount, ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfDayODS> iterable, Collector<AdStatOfDayDWD> collector) throws Exception {
                         AdDataOfDayODS element = iterable.iterator().next();
+                        Long adId = element.getAdId();
                         LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
                         long now = System.currentTimeMillis();
-                        // 拉取指定 key的数据
-                        if (historyData == null || (now - lastQueryTime) > 60 * 60 * 1000) {
+
+                        Map<String, AdStatOfDayDWD> historyData = historyAdData.computeIfAbsent(adId, key -> new HashMap<>());
+                        Long lastQueryTime = lastAdQueryTime.get(adId);
+                        // 从 maxCompute查找广告的历史数据
+                        if (lastQueryTime == null || (now - lastQueryTime) > 60 * 60 * 1000) {
                             LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(60);
                             Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_day_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
                             instance.waitForSuccess();
                             List<Record> records = SQLTask.getResult(instance);
-                            historyData = records.stream()
+                            List<AdStatOfDayDWD> list = records.stream()
                                     .map(AdStatOfDayDWD::byMaxCompute)
-                                    .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue())
-                                    .collect(Collectors.toMap(AdStatOfDayDWD::getStatDay, value -> value, (val1, val2) -> val2));
-                            lastQueryTime = now;
+                                    .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue()).collect(Collectors.toList());
+                            for (AdStatOfDayDWD adStatOfDayDWD : list) {
+                                historyData.put(adStatOfDayDWD.getStatDay(), adStatOfDayDWD);
+                            }
+                            lastAdQueryTime.put(adId, now);
                         }
                         AdStatOfDayDWD newStatData = null;
                         for (int i = 1; i <= 60; i++) {
@@ -364,7 +477,7 @@ public class KafkaDemoJob {
                     }
                 }).addSink(new TunnelBatchSink<>(AdStatOfDayDWD.class, 30000L, 365L, 6));
 
-        adDayOdsStreamSplit.getSideOutput(adDayStreamRollYearTag)
+        adDayODSStreamSplit.getSideOutput(adDayStreamRollYearTag)
                 .keyBy((KeySelector<AdDataOfDayODS, Long>) AdDataOfDayODS::getAdId)
                 .countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
                     // 上次聚合的结果

+ 1 - 1
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/KafkaBatchJob.java → flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/BatchJob.java

@@ -5,7 +5,7 @@ import org.apache.flink.api.java.ExecutionEnvironment;
 /**
  * 看起来有点鸡肋
  */
-public class KafkaBatchJob {
+public class BatchJob {
     public static void main(String[] args) throws Exception {
         final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
 

+ 574 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/PlanStatJob.java

@@ -0,0 +1,574 @@
+package flink.zanxiangnet.ad.monitoring;
+
+import com.aliyun.odps.Instance;
+import com.aliyun.odps.Odps;
+import com.aliyun.odps.account.Account;
+import com.aliyun.odps.account.AliyunAccount;
+import com.aliyun.odps.data.Record;
+import com.aliyun.odps.task.SQLTask;
+import com.tencent.ads.model.DailyReportsGetListStruct;
+import com.tencent.ads.model.HourlyReportsGetListStruct;
+import flink.zanxiangnet.ad.monitoring.maxcompute.MaxComputeLog;
+import flink.zanxiangnet.ad.monitoring.maxcompute.sink.TunnelBatchSink;
+import flink.zanxiangnet.ad.monitoring.pojo.dto.AdDataOfDayDTO;
+import flink.zanxiangnet.ad.monitoring.pojo.dto.AdDataOfMinuteDTO;
+import flink.zanxiangnet.ad.monitoring.pojo.dto.AdStatOfDayODSDTO;
+import flink.zanxiangnet.ad.monitoring.pojo.entity.*;
+import flink.zanxiangnet.ad.monitoring.pojo.properties.ApplicationProperties;
+import flink.zanxiangnet.ad.monitoring.pojo.properties.KafkaProperties;
+import flink.zanxiangnet.ad.monitoring.util.DateUtil;
+import flink.zanxiangnet.ad.monitoring.util.JsonUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
+import org.apache.flink.api.common.eventtime.WatermarkStrategy;
+import org.apache.flink.api.common.serialization.SimpleStringSchema;
+import org.apache.flink.api.java.functions.KeySelector;
+import org.apache.flink.configuration.Configuration;
+import org.apache.flink.connector.kafka.source.KafkaSource;
+import org.apache.flink.connector.kafka.source.enumerator.initializer.OffsetsInitializer;
+import org.apache.flink.streaming.api.datastream.DataStream;
+import org.apache.flink.streaming.api.datastream.DataStreamSource;
+import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
+import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
+import org.apache.flink.streaming.api.functions.ProcessFunction;
+import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
+import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
+import org.apache.flink.streaming.api.windowing.time.Time;
+import org.apache.flink.streaming.api.windowing.windows.GlobalWindow;
+import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
+import org.apache.flink.util.Collector;
+import org.apache.flink.util.OutputTag;
+import org.apache.kafka.clients.CommonClientConfigs;
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+import org.apache.kafka.clients.consumer.OffsetResetStrategy;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.config.SaslConfigs;
+import org.apache.kafka.common.config.SslConfigs;
+import org.springframework.beans.BeanUtils;
+
+import java.time.Duration;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+public class PlanStatJob {
+
+    /**
+     * 可能有数据的最早日期
+     */
+    private static final String OLDEST_DAY = "2019-01-01";
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("javax.net.ssl.trustStore", "D:\\Downloads\\kafka.client.truststore.jks");
+        // System.setProperty("javax.net.ssl.trustStore", "/root/flink-1.13.2/kafka.client.truststore.jks");
+        System.setProperty("javax.net.ssl.trustStorePassword", "KafkaOnsClient");
+        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+
+        // 加载配置文件到 flink的全局配置中
+        Properties props = new Properties();
+        props.load(PlanStatJob.class.getResourceAsStream("/application.properties"));
+        Configuration configuration = new Configuration();
+        props.stringPropertyNames().forEach(key -> {
+            String value = props.getProperty(key);
+            configuration.setString(key.trim(), StringUtils.isBlank(value) ? "" : value.trim());
+        });
+        env.getConfig().setGlobalJobParameters(configuration);
+
+        Properties adStreamOfMinuteProps = new Properties();
+        adStreamOfMinuteProps.load(PlanStatJob.class.getResourceAsStream("/ad_stream_of_minute.properties"));
+        KafkaSource<String> adStreamOfMinuteSource = buildKafkaSource(adStreamOfMinuteProps);
+
+        DataStreamSource<String> adStreamOfMinuteIn = env.fromSource(adStreamOfMinuteSource, WatermarkStrategy.noWatermarks(), "adStreamOfMinuteSource_kafka");
+
+        // 广告分钟数据(前 5分钟的广告消耗数据)
+        final OutputTag<AdDataOfMinuteODS> adMinuteStreamTag = new OutputTag<AdDataOfMinuteODS>("adMinuteStream") {
+        };
+        // 广告小时数据(往前回滚 10天)
+        final OutputTag<AdDataOfHourODS> adHourStreamTag = new OutputTag<AdDataOfHourODS>("adHourStream") {
+        };
+
+        // 对流进行映射,拆分(实时的分钟流和回滚的小时流)
+        SingleOutputStreamOperator<AdDataOfMinuteODS> adODSStream = adStreamOfMinuteIn.filter(StringUtils::isNotBlank)
+                .process(new ProcessFunction<String, AdDataOfMinuteODS>() {
+                    @Override
+                    public void processElement(String adDataStr, ProcessFunction<String, AdDataOfMinuteODS>.Context context, Collector<AdDataOfMinuteODS> collector) throws Exception {
+                        AdDataOfMinuteDTO dto = JsonUtil.toObj(adDataStr, AdDataOfMinuteDTO.class);
+                        // 指记录被创建的时间
+                        long createTime = dto.getCreateTime();
+                        // 指记录统计的时间(如果是实时统计的数据精确到分钟,回滚的历史数据精确到天)
+                        long statTime = DateUtil.localDateTimeToMilli(DateUtil.milliToLocalDateTime(dto.getDataTime()).withSecond(0).withNano(0));
+                        HourlyReportsGetListStruct struct = dto.getHourlyReportsGetListStruct();
+
+                        if (createTime - statTime > (60 * 60 * 1000L)) {
+                            AdDataOfHourODS adODS = new AdDataOfHourODS();
+                            BeanUtils.copyProperties(struct, adODS);
+                            adODS.setStatDay(DateUtil.formatLocalDate(DateUtil.milliToLocalDate(statTime)));
+                            adODS.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
+                            adODS.setStatTime(DateUtil.localDateTimeToMilli(DateUtil.milliToLocalDateTime(statTime).withMinute(0)));
+                            adODS.setAccountId(dto.getAccountId());
+                            adODS.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
+                            adODS.setCreateTime(new Date(createTime));
+                            context.output(adHourStreamTag, adODS);
+                        } else {
+                            AdDataOfMinuteODS adODS = new AdDataOfMinuteODS();
+                            BeanUtils.copyProperties(struct, adODS);
+                            adODS.setStatDay(DateUtil.formatLocalDate(DateUtil.milliToLocalDate(statTime)));
+                            adODS.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
+                            adODS.setStatTime(statTime);
+                            adODS.setAccountId(dto.getAccountId());
+                            adODS.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
+                            adODS.setCreateTime(new Date(createTime));
+                            context.output(adMinuteStreamTag, adODS);
+                        }
+                    }
+                });
+
+        // 分钟流
+        DataStream<AdDataOfMinuteODS> adMinuteODSStream = adODSStream.getSideOutput(adMinuteStreamTag);
+        // 写入原始表
+        adMinuteODSStream.addSink(new TunnelBatchSink<>(AdDataOfMinuteODS.class, 36000L, 64000L, 3));
+        adMinuteODSStream
+                // 打水印,允许数据延迟 6分钟,同时指定时间流
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfMinuteODS>forBoundedOutOfOrderness(Duration.ofMinutes(6L))
+                        .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfMinuteODS>) (adODS, l) -> adODS.getStatTime()))
+                .keyBy(AdDataOfMinuteODS::getAdId)
+                // 开一个 5分钟的滚动窗口
+                .window(TumblingEventTimeWindows.of(Time.minutes(5L)))
+                .process(new ProcessWindowFunction<AdDataOfMinuteODS, AdStatOfMinuteDWD, Long, TimeWindow>() {
+                    // 对象锁,防止MaxCompute的 Tunnel对象多次初始化
+                    private final String DUMMY_LOCK = "DUMMY_LOCK";
+                    private Odps odps;
+                    private long lastClearTime = System.currentTimeMillis();
+                    private final Map<Long, String> lastAdDayQueryDay = new ConcurrentHashMap<>();
+                    // 历史的天数据
+                    private final Map<Long, AdStatOfDayDWD> historyDayData = new ConcurrentHashMap<>();
+                    // 之前聚合的昨天的数据
+                    private final Map<Long, Map<String, AdStatOfMinuteDWD>> historyMinuteData = new ConcurrentHashMap<>();
+                    // 前 5分钟聚合的数据
+                    private final Map<Long, Map<String, AdStatOfMinuteDWD>> lastReduceData = new ConcurrentHashMap<>();
+
+                    private void clearData() {
+                        lastAdDayQueryDay.entrySet().removeIf(entry -> DateUtil.parseLocalDate(entry.getValue()).compareTo(LocalDate.now().minusDays(3L)) <= 0);
+                        historyDayData.entrySet().removeIf(entry -> DateUtil.parseLocalDate(entry.getValue().getStatDay()).compareTo(LocalDate.now().minusDays(50L)) <= 0);
+                        historyMinuteData.forEach((key, value) -> {
+                            if (value != null) {
+                                value.entrySet().removeIf(entry2 -> DateUtil.parseLocalDate(entry2.getKey()).compareTo(LocalDate.now().minusDays(3L)) <= 0);
+                            }
+                        });
+                        historyMinuteData.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().isEmpty());
+
+                        lastReduceData.forEach((key, value) -> {
+                            if (value != null) {
+                                value.entrySet().removeIf(entry -> DateUtil.parseOfMinuteReduce(entry.getKey()).compareTo(LocalDateTime.now().minusHours(1)) <= 0);
+                            }
+                        });
+                        lastReduceData.entrySet().removeIf(entry -> entry.getValue() == null || entry.getValue().isEmpty());
+                    }
+
+                    @Override
+                    public void open(Configuration conf) {
+                        Map<String, String> params = getRuntimeContext()
+                                .getExecutionConfig()
+                                .getGlobalJobParameters()
+                                .toMap();
+                        Account account = new AliyunAccount(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ID),
+                                params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_KEY));
+                        odps = new Odps(account);
+                        odps.getRestClient().setRetryLogger(new MaxComputeLog());
+                        odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
+                        odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
+                    }
+
+                    @Override
+                    public void process(Long elementCount, ProcessWindowFunction<AdDataOfMinuteODS, AdStatOfMinuteDWD, Long, TimeWindow>.Context context,
+                                        Iterable<AdDataOfMinuteODS> iterable, Collector<AdStatOfMinuteDWD> collector) throws Exception {
+                        LocalDateTime beginTime = DateUtil.milliToLocalDateTime(context.window().getStart());
+                        String statDay = DateUtil.formatLocalDate(beginTime.toLocalDate());
+                        String reduceTimeKey = DateUtil.formatOfMinuteReduce(beginTime);
+                        int hour = beginTime.getHour();
+                        long now = System.currentTimeMillis();
+                        AdDataOfMinuteODS statODS = null;
+                        List<AdDataOfMinuteODS> adDataOfMinuteODSList = new ArrayList<>(24);
+                        for (AdDataOfMinuteODS adDataOfMinuteODS : iterable) {
+                            adDataOfMinuteODSList.add(adDataOfMinuteODS);
+                            if (adDataOfMinuteODS.getHour() != hour) {
+                                continue;
+                            }
+                            statODS = adDataOfMinuteODS;
+                            break;
+                        }
+                        if (statODS == null) {
+                            return;
+                        }
+
+                        // 每 12小时清理一次数据
+                        if (now - lastClearTime > 12 * 60 * 60 * 1000) {
+                            synchronized (DUMMY_LOCK) {
+                                if (now - lastClearTime > 12 * 60 * 60 * 1000) {
+                                    clearData();
+                                    lastClearTime = now;
+                                }
+                            }
+                        }
+                        Long adId = statODS.getAdId();
+
+                        // 昨天聚合的数据
+                        Map<String, AdStatOfMinuteDWD> historyMinuteMapping = historyMinuteData.computeIfAbsent(adId, key -> new HashMap<>());
+                        AdStatOfMinuteDWD yesterdayMinuteDWD = historyMinuteMapping.get(DateUtil.formatLocalDate(beginTime.minusDays(1L).toLocalDate()));
+                        // 之前的数据
+                        String lastQueryDay = lastAdDayQueryDay.get(adId);
+                        if (lastQueryDay == null || !lastQueryDay.equals(statDay)) {
+                            // 往前找 30天
+                            LocalDate endDay = beginTime.minusDays(2L).toLocalDate(), beginDay = endDay.minusDays(30L);
+                            Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_day_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginDay) + "\" AND stat_day <= \"" + endDay + "\" AND ad_id = " + adId + ";");
+                            instance.waitForSuccess();
+                            List<Record> records = SQLTask.getResult(instance);
+                            List<AdStatOfDayDWD> temp = records.stream().map(AdStatOfDayDWD::byMaxCompute).sorted((val1, val2) -> {
+                                if (val1.getStatDay().equals(val2.getStatDay())) {
+                                    return new Long(val1.getCreateTime().getTime() - val2.getCreateTime().getTime()).intValue();
+                                }
+                                return DateUtil.parseLocalDate(val1.getStatDay()).compareTo(DateUtil.parseLocalDate(val2.getStatDay()));
+                            }).collect(Collectors.toList());
+                            historyDayData.put(adId, temp.isEmpty() ? null : temp.get(temp.size() - 1));
+                            lastAdDayQueryDay.put(adId, statDay);
+                        }
+                        AdStatOfDayDWD beforeYesterdayDayDWD = historyDayData.get(adId);
+                        Map<String, AdStatOfMinuteDWD> lastReduceMapping = lastReduceData.computeIfAbsent(adId, key -> new HashMap<>());
+                        // 聚合当天的全部数据
+                        AdStatOfMinuteDWD nowAdStat = AdStatOfMinuteDWD.reduce(beforeYesterdayDayDWD, yesterdayMinuteDWD, adDataOfMinuteODSList, statODS, lastReduceMapping.get(DateUtil.formatOfMinuteReduce(beginTime.minusMinutes(5L))), now);
+                        collector.collect(nowAdStat);
+                        lastReduceMapping.put(reduceTimeKey, nowAdStat);
+                        historyMinuteMapping.put(statDay, nowAdStat);
+                    }
+                }).addSink(new TunnelBatchSink<>(AdStatOfMinuteDWD.class, 30000L, 365L, 6));
+        ;
+
+        // 小时流(直接写到小时报表的 ods)
+        DataStream<AdDataOfHourODS> adHourODSStream = adODSStream.getSideOutput(adHourStreamTag);
+        // 写入原始表
+        adHourODSStream.addSink(new TunnelBatchSink<>(AdDataOfHourODS.class, 36000L, 64000L, 10));
+        adHourODSStream.keyBy(AdDataOfHourODS::getAdId)
+                .countWindow(1).process(new ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>() {
+                    private Odps odps;
+                    private final Map<Long, Long> lastAdQueryTime = new ConcurrentHashMap<>();
+                    private final Map<Long, Map<String, Map<Integer, AdStatOfHourDWD>>> historyAdData = new ConcurrentHashMap<>();
+
+                    @Override
+                    public void open(Configuration conf) {
+                        Map<String, String> params = getRuntimeContext()
+                                .getExecutionConfig()
+                                .getGlobalJobParameters()
+                                .toMap();
+                        Account account = new AliyunAccount(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ID),
+                                params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_KEY));
+                        odps = new Odps(account);
+                        odps.getRestClient().setRetryLogger(new MaxComputeLog());
+                        odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
+                        odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
+                    }
+
+                    @Override
+                    public void process(Long elementsCount, ProcessWindowFunction<AdDataOfHourODS, AdStatOfHourDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfHourODS> iterable, Collector<AdStatOfHourDWD> collector) throws Exception {
+                        AdDataOfHourODS element = iterable.iterator().next();
+                        LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
+                        Integer hour = element.getHour();
+                        long now = System.currentTimeMillis();
+                        Long adId = element.getAdId();
+
+                        Map<String, Map<Integer, AdStatOfHourDWD>> historyData = historyAdData.computeIfAbsent(adId, key -> new HashMap<>());
+                        Long lastQueryTime = lastAdQueryTime.get(adId);
+                        // 从 maxCompute拉取指定 广告的历史数据
+                        if (lastQueryTime == null || (now - lastQueryTime) > 3 * 60 * 60 * 1000) {
+                            LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(40);
+                            Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_hour_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
+                            instance.waitForSuccess();
+                            List<Record> records = SQLTask.getResult(instance);
+                            List<AdStatOfHourDWD> historyList = records.stream()
+                                    .map(AdStatOfHourDWD::byMaxCompute)
+                                    .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue())
+                                    .collect(Collectors.toList());
+                            for (AdStatOfHourDWD adStatOfHourDWD : historyList) {
+                                Map<Integer, AdStatOfHourDWD> hourMapping = historyData.computeIfAbsent(adStatOfHourDWD.getStatDay(), key -> new HashMap<>());
+                                hourMapping.put(adStatOfHourDWD.getHour(), adStatOfHourDWD);
+                            }
+                            lastAdQueryTime.put(adId, now);
+                        }
+                        // 找到这个号当天内上个小时统计的数据
+                        AdStatOfHourDWD lastHourData = null;
+                        // 往前查 40天,找到广告上一次聚合的数据
+                        for (int i = 0; i < 40; i++) {
+                            Map<Integer, AdStatOfHourDWD> mapData = historyData.get(DateUtil.formatLocalDate(statDay.minusDays(i)));
+                            if (mapData == null || mapData.isEmpty()) {
+                                continue;
+                            }
+                            for (Map.Entry<Integer, AdStatOfHourDWD> temp : mapData.entrySet()) {
+                                if (temp.getKey() >= hour) {
+                                    continue;
+                                }
+                                if (lastHourData != null && lastHourData.getHour() >= temp.getKey()) {
+                                    continue;
+                                }
+                                lastHourData = temp.getValue();
+                            }
+                            if (lastHourData != null) {
+                                break;
+                            }
+                        }
+                        AdStatOfHourDWD newStatData = AdStatOfHourDWD.reduce(lastHourData, element, now);
+                        Map<Integer, AdStatOfHourDWD> hourDataMapping = historyData.computeIfAbsent(newStatData.getStatDay(), key -> new HashMap<>());
+                        hourDataMapping.put(newStatData.getHour(), newStatData);
+                        collector.collect(newStatData);
+                    }
+                }).addSink(new TunnelBatchSink<>(AdStatOfHourDWD.class, 30000L, 365L, 6));
+
+        // 获取指定广告的历史统计信息(用于统计总的消耗信息等)
+        /*SingleOutputStreamOperator<AdStatOfHourDWD> adHourDWDStream = adHourODSStream.map(AdStatOfHourDWD::byODS)
+                .keyBy((KeySelector<AdStatOfHourDWD, String>) adHourDWD -> adHourDWD.getStatDay() + "_" + adHourDWD.getAdId())
+                // 开一个按天滚动的窗口
+                .window(TumblingEventTimeWindows.of(Time.days(1L)))
+                // 数据聚合
+                .reduce(new RichReduceFunction<AdStatOfHourDWD>() {
+                    // 初始化 MaxCompute连接实例
+                    private Odps odps;
+
+                    @Override
+                    public void open(Configuration parameters) throws Exception {
+                        Map<String, String> params = getRuntimeContext()
+                                .getExecutionConfig()
+                                .getGlobalJobParameters()
+                                .toMap();
+                        Account account = new AliyunAccount(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ID),
+                                params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_KEY));
+                        Odps odps = new Odps(account);
+                        odps.getRestClient().setRetryLogger(new MaxComputeLog());
+                        odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
+                        odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
+                    }
+
+                    @Override
+                    public AdStatOfHourDWD reduce(AdStatOfHourDWD adStatOfHourDWD, AdStatOfHourDWD t1) {
+                        Long accountId = adStatOfHourDWD.getAccountId();
+                        Long campaignId = adStatOfHourDWD.getCampaignId();
+                        Long adId = adStatOfHourDWD.getAdId();
+                        String statDay = adStatOfHourDWD.getStatDay();
+                        // 1、从 MaxCompute取出小时数据往前的所有无重复按天统计的数据,并聚合用来算总的
+                        // 2、当前流的所有数据聚合在一起作为天数据
+                        // 3、写出到 MaxCompute
+                        return null;
+                    }
+                });*/
+
+
+        // ------------------------------------------------------- 处理广告的天数据 -----------------------------------------
+        Properties adStreamOfDayProps = new Properties();
+        adStreamOfDayProps.load(PlanStatJob.class.getResourceAsStream("/ad_stream_of_day.properties"));
+        KafkaSource<String> adStreamOfDaySource = buildKafkaSource(adStreamOfDayProps);
+
+        DataStreamSource<String> adStreamOfDayIn = env.fromSource(adStreamOfDaySource, WatermarkStrategy.noWatermarks(), "adStreamOfMinuteSource_kafka");
+
+        // 广告日数据。往前回滚 10天
+        final OutputTag<AdDataOfDayODS> adDayStreamRollDayTag = new OutputTag<AdDataOfDayODS>("adDayStreamRollDayTag") {
+        };
+        // 广告日数据。往前回滚 1年
+        final OutputTag<AdDataOfDayODS> adDayStreamRollYearTag = new OutputTag<AdDataOfDayODS>("adDayStreamRollYearTag") {
+        };
+        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayODSStream = adStreamOfDayIn.filter(StringUtils::isNotBlank)
+                .map(str -> {
+                    AdDataOfDayDTO dto = JsonUtil.toObj(str, AdDataOfDayDTO.class);
+                    Date createTime = new Date(dto.getCreateTime());
+                    DailyReportsGetListStruct struct = dto.getDailyReportsGetListStruct();
+                    AdDataOfDayODS adODS = new AdDataOfDayODS();
+                    BeanUtils.copyProperties(struct, adODS);
+                    adODS.setStatDay(struct.getDate());
+                    adODS.setAccountId(dto.getAccountId());
+                    adODS.setCampaignId(struct.getCampaignId());
+                    adODS.setAgencyAccountId(struct.getAccountId());
+                    adODS.setWechatAccountId(struct.getWechatAccountId());
+                    adODS.setAdgroupId(struct.getAdgroupId());
+                    adODS.setAdId(struct.getAdId());
+                    adODS.setCreateTime(createTime);
+                    return AdStatOfDayODSDTO.builder()
+                            .startDate(dto.getStartDate())
+                            .endDate(dto.getEndDate())
+                            .adDataOfDayODS(adODS)
+                            .build();
+                });
+        adDayODSStream.map(AdStatOfDayODSDTO::getAdDataOfDayODS).addSink(new TunnelBatchSink<>(AdDataOfDayODS.class, 36000L, 6000L, 10));
+
+        // 拆分流
+        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayODSStreamSplit = adDayODSStream.process(new ProcessFunction<AdStatOfDayODSDTO, AdStatOfDayODSDTO>() {
+            @Override
+            public void processElement(AdStatOfDayODSDTO adDataDTO, ProcessFunction<AdStatOfDayODSDTO, AdStatOfDayODSDTO>.Context context, Collector<AdStatOfDayODSDTO> collector) throws Exception {
+                LocalDate startDate = adDataDTO.getStartDate();
+                LocalDate endDate = adDataDTO.getEndDate();
+                AdDataOfDayODS adODS = adDataDTO.getAdDataOfDayODS();
+                if (DateUtil.intervalOfDays(startDate, endDate) > 31L) {
+                    // 拉取时间间隔超过 1个月,账号回滚 365天的数据
+                    context.output(adDayStreamRollYearTag, adODS);
+                } else {
+                    // 每日往前回滚 10天的数据
+                    context.output(adDayStreamRollDayTag, adODS);
+                }
+            }
+        });
+
+        adDayODSStreamSplit.getSideOutput(adDayStreamRollDayTag)
+                // 打水印,允许延迟 10天(应为允许回滚 10天),同时指定事件时间
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfDayODS>forBoundedOutOfOrderness(Duration.ofDays(10L))
+                        .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfDayODS>) (adDay, l) -> DateUtil.localDateToMilli(DateUtil.parseLocalDate(adDay.getStatDay())))
+                ).keyBy(AdDataOfDayODS::getAdId)
+                .countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
+                    private Odps odps;
+                    private final Map<Long, Long> lastAdQueryTime = new ConcurrentHashMap<>();
+                    private final Map<Long, Map<String, AdStatOfDayDWD>> historyAdData = new ConcurrentHashMap<>();
+
+                    @Override
+                    public void open(Configuration conf) {
+                        Map<String, String> params = getRuntimeContext()
+                                .getExecutionConfig()
+                                .getGlobalJobParameters()
+                                .toMap();
+                        Account account = new AliyunAccount(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ID),
+                                params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_KEY));
+                        odps = new Odps(account);
+                        odps.getRestClient().setRetryLogger(new MaxComputeLog());
+                        odps.setEndpoint(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_ENDPOINT));
+                        odps.setDefaultProject(params.get(ApplicationProperties.MAX_COMPUTE_ACCOUNT_PROJECT_NAME));
+                    }
+
+                    @Override
+                    public void process(Long elementsCount, ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfDayODS> iterable, Collector<AdStatOfDayDWD> collector) throws Exception {
+                        AdDataOfDayODS element = iterable.iterator().next();
+                        Long adId = element.getAdId();
+                        LocalDate statDay = DateUtil.parseLocalDate(element.getStatDay());
+                        long now = System.currentTimeMillis();
+
+                        Map<String, AdStatOfDayDWD> historyData = historyAdData.computeIfAbsent(adId, key -> new HashMap<>());
+                        Long lastQueryTime = lastAdQueryTime.get(adId);
+                        // 从 maxCompute查找广告的历史数据
+                        if (lastQueryTime == null || (now - lastQueryTime) > 60 * 60 * 1000) {
+                            LocalDate endTime = LocalDate.now(), beginTime = statDay.minusDays(60);
+                            Instance instance = SQLTask.run(odps, "SELECT * FROM ad_stat_of_day_dwd WHERE stat_day >= \"" + DateUtil.formatLocalDate(beginTime) + "\" AND stat_day <= \"" + DateUtil.formatLocalDate(endTime) + "\" AND ad_id = " + element.getAdId() + ";");
+                            instance.waitForSuccess();
+                            List<Record> records = SQLTask.getResult(instance);
+                            List<AdStatOfDayDWD> list = records.stream()
+                                    .map(AdStatOfDayDWD::byMaxCompute)
+                                    .sorted((o1, o2) -> new Long(o1.getCreateTime().getTime() - o2.getCreateTime().getTime()).intValue()).collect(Collectors.toList());
+                            for (AdStatOfDayDWD adStatOfDayDWD : list) {
+                                historyData.put(adStatOfDayDWD.getStatDay(), adStatOfDayDWD);
+                            }
+                            lastAdQueryTime.put(adId, now);
+                        }
+                        AdStatOfDayDWD newStatData = null;
+                        for (int i = 1; i <= 60; i++) {
+                            AdStatOfDayDWD oldStatData = historyData.get(DateUtil.formatLocalDate(statDay.minusDays(i)));
+                            if (oldStatData == null) {
+                                continue;
+                            }
+                            newStatData = AdStatOfDayDWD.reduce(oldStatData, element, now);
+                            break;
+                        }
+                        if (newStatData == null) {
+                            newStatData = AdStatOfDayDWD.reduce(null, element, now);
+                        }
+                        historyData.put(newStatData.getStatDay(), newStatData);
+                        collector.collect(newStatData);
+                    }
+                }).addSink(new TunnelBatchSink<>(AdStatOfDayDWD.class, 30000L, 365L, 6));
+
+        adDayODSStreamSplit.getSideOutput(adDayStreamRollYearTag)
+                .keyBy((KeySelector<AdDataOfDayODS, Long>) AdDataOfDayODS::getAdId)
+                .countWindow(1).process(new ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>() {
+                    // 上次聚合的结果
+                    private AdStatOfDayDWD lastReduce;
+
+                    @Override
+                    public void process(Long elementsCount, ProcessWindowFunction<AdDataOfDayODS, AdStatOfDayDWD, Long, GlobalWindow>.Context context, Iterable<AdDataOfDayODS> elements, Collector<AdStatOfDayDWD> out) {
+                        AdDataOfDayODS element = elements.iterator().next();
+                        lastReduce = AdStatOfDayDWD.reduce(lastReduce, element, System.currentTimeMillis());
+                        out.collect(lastReduce);
+                    }
+                }).addSink(new TunnelBatchSink<>(AdStatOfDayDWD.class, 30000L, 365L, 6));
+
+        env.execute();
+    }
+
+    private static KafkaSource<String> buildKafkaSource(Properties props) {
+        return buildKafkaSource(props.getProperty(KafkaProperties.KAFKA_SERVERS),
+                props.getProperty(KafkaProperties.KAFKA_USERNAME),
+                props.getProperty(KafkaProperties.KAFKA_PASSWORD),
+                props.getProperty(KafkaProperties.KAFKA_SSL_PATH),
+                props.getProperty(KafkaProperties.KAFKA_TOPIC),
+                props.getProperty(KafkaProperties.KAFKA_GROUP_ID)
+        );
+    }
+
+    /**
+     * 内网
+     *
+     * @param servers
+     * @param username
+     * @param password
+     * @param sslPath
+     * @param topic
+     * @param groupId
+     * @return
+     */
+    private static KafkaSource<String> buildKafkaSourceVPC(String servers, String username, String password, String sslPath, String topic, String groupId) {
+        Properties props = new Properties();
+        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers);
+        //两次Poll之间的最大允许间隔。
+        //消费者超过该值没有返回心跳,服务端判断消费者处于非存活状态,服务端将消费者从Group移除并触发Rebalance,默认30s。
+        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 30000);
+        //每次Poll的最大数量。
+        //注意该值不要改得太大,如果Poll太多数据,而不能在下次Poll之前消费完,则会触发一次负载均衡,产生卡顿。
+        props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 30);
+        //消息的反序列化方式。
+        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
+        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
+        //当前消费实例所属的消费组,请在控制台申请之后填写。
+        //属于同一个组的消费实例,会负载消费消息。
+        props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
+        return KafkaSource.<String>builder()
+                .setProperties(props)
+                .setBootstrapServers(servers)
+                .setTopics(topic)
+                .setGroupId(groupId)
+                .setStartingOffsets(OffsetsInitializer.committedOffsets(OffsetResetStrategy.EARLIEST))
+                .setValueOnlyDeserializer(new SimpleStringSchema())
+                .build();
+    }
+
+    /**
+     * 公网
+     *
+     * @param servers
+     * @param username
+     * @param password
+     * @param sslPath
+     * @param topic
+     * @param groupId
+     * @return
+     */
+    private static KafkaSource<String> buildKafkaSource(String servers, String username, String password, String sslPath, String topic, String groupId) {
+        Properties props = new Properties();
+        props.put(SaslConfigs.SASL_JAAS_CONFIG, "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"" + username + "\" password=\"" + password + "\";");
+        props.put(SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, sslPath);
+        props.put(SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, "KafkaOnsClient");
+        props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, "SASL_SSL");
+        props.put(SaslConfigs.SASL_MECHANISM, "PLAIN");
+        props.put(SslConfigs.SSL_ENDPOINT_IDENTIFICATION_ALGORITHM_CONFIG, "");
+        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+        return KafkaSource.<String>builder()
+                .setBootstrapServers(servers)
+                .setTopics(topic)
+                .setGroupId(groupId)
+                .setProperties(props)
+                .setStartingOffsets(OffsetsInitializer.committedOffsets(OffsetResetStrategy.EARLIEST))
+                .setValueOnlyDeserializer(new SimpleStringSchema())
+                .build();
+    }
+}

+ 14 - 8
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/Test.java

@@ -30,7 +30,10 @@ import org.apache.flink.util.Collector;
 import java.time.Duration;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -41,6 +44,8 @@ public class Test {
     public static void main(String[] args) throws Exception {
         StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
 
+        env.setParallelism(1);
+
         DataStreamSource<Pojo> source = env.addSource(new PojoSource());
         // 打水印,延迟 2秒,同时指定时间流
         SingleOutputStreamOperator<Pojo> pojoStream = source.assignTimestampsAndWatermarks(WatermarkStrategy.<Pojo>forBoundedOutOfOrderness(Duration.ofHours(2))
@@ -75,19 +80,20 @@ public class Test {
                 }).print();*/
         pojoStream.keyBy(Pojo::getUserId).countWindow(1)
                 .process(new ProcessWindowFunction<Pojo, String, Integer, GlobalWindow>() {
-                    private Integer lastUserId = null;
-                    private Tuple3<LocalDateTime, LocalDateTime, List<Pojo>> oldData = null;
+                    private final Map<Integer, Tuple3<LocalDateTime, LocalDateTime, List<Pojo>>> oldData = new ConcurrentHashMap<>();
+
                     @Override
                     public void process(Integer integer, ProcessWindowFunction<Pojo, String, Integer, GlobalWindow>.Context context, Iterable<Pojo> elements, Collector<String> out) throws Exception {
                         Pojo pojo = elements.iterator().next();
                         LocalDateTime createTime = DateUtil.milliToLocalDateTime(pojo.getCreateTime());
-                        if (oldData == null || createTime.getDayOfYear() != oldData.f1.getDayOfYear()) {
-                            oldData = new Tuple3<>(createTime, createTime, new ArrayList<>(200));
+                        Tuple3<LocalDateTime, LocalDateTime, List<Pojo>> temp = oldData.get(pojo.getUserId());
+                        if (temp == null || createTime.getDayOfYear() != temp.f1.getDayOfYear()) {
+                            temp = new Tuple3<>(createTime, createTime, new ArrayList<>(200));
                         }
-                        lastUserId = pojo.getUserId();
-                        oldData.f2.add(pojo);
-                        oldData.setField(createTime, 1);
-                        out.collect(JsonUtil.toString(oldData.f2.stream().map(Pojo::getIndex).collect(Collectors.toList())));
+                        temp.f2.add(pojo);
+                        temp.setField(createTime, 1);
+                        oldData.put(pojo.getUserId(), temp);
+                        out.collect(JsonUtil.toString(temp.f2.stream().map(Pojo::getIndex).collect(Collectors.toList())));
                     }
                 }).print();
 /*        .apply(new WindowFunction<Pojo, String, Integer, GlobalWindow>() {

+ 1 - 1
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdDataOfHourODS.java

@@ -31,7 +31,7 @@ public class AdDataOfHourODS implements Serializable {
     private Integer hour;
 
     /**
-     * 统计发起时间
+     * 统计发起时间(分、秒、毫秒应该都是 0)
      */
     @SerializedName("stat_time")
     private Long statTime;

+ 0 - 87
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfDayDWD.java

@@ -948,93 +948,6 @@ public class AdStatOfDayDWD implements Serializable {
     @SerializedName("no_interest_count_day")
     private Long noInterestCountDay;
 
-    public static AdStatOfDayDWD byOds(AdDataOfDayODS dayOds) {
-        AdStatOfDayDWD adStatOfDay = new AdStatOfDayDWD();
-        adStatOfDay.setStatDay(dayOds.getStatDay());
-        adStatOfDay.setAccountId(dayOds.getAccountId());
-        adStatOfDay.setCampaignId(dayOds.getCampaignId());
-        adStatOfDay.setAgencyAccountId(dayOds.getAgencyAccountId());
-        adStatOfDay.setWechatAccountId(dayOds.getWechatAccountId());
-        adStatOfDay.setWechatAgencyId(dayOds.getWechatAgencyId());
-        adStatOfDay.setAdgroupId(dayOds.getAdgroupId());
-        adStatOfDay.setAdId(dayOds.getAdId());
-        adStatOfDay.setCreateTime(new Date());
-        adStatOfDay.setCostDeviationRateDay(dayOds.getCostDeviationRate());
-        adStatOfDay.setCostDay(dayOds.getCost());
-        adStatOfDay.setCompensationAmountDay(dayOds.getCompensationAmount());
-        adStatOfDay.setViewCountDay(dayOds.getViewCount());
-        adStatOfDay.setThousandDisplayPriceDay(dayOds.getThousandDisplayPrice());
-        adStatOfDay.setViewUserCountDay(dayOds.getViewUserCount());
-        adStatOfDay.setAvgViewPerUserDay(dayOds.getAvgViewPerUser());
-        adStatOfDay.setValidClickCountDay(dayOds.getValidClickCount());
-        adStatOfDay.setClickUserCountDay(dayOds.getClickUserCount());
-        adStatOfDay.setCtrDay(dayOds.getCtr());
-        adStatOfDay.setCpcDay(dayOds.getCpc());
-        adStatOfDay.setValuableClickCountDay(dayOds.getValuableClickCount());
-        adStatOfDay.setValuableClickRateDay(dayOds.getValuableClickRate());
-        adStatOfDay.setValuableClickCostDay(dayOds.getValuableClickCost());
-        adStatOfDay.setConversionsCountDay(dayOds.getConversionsCount());
-        adStatOfDay.setConversionsCostDay(dayOds.getConversionsCost());
-        adStatOfDay.setConversionsRateDay(dayOds.getConversionsRate());
-        adStatOfDay.setDeepConversionsCountDay(dayOds.getDeepConversionsCount());
-        adStatOfDay.setDeepConversionsCostDay(dayOds.getDeepConversionsCost());
-        adStatOfDay.setDeepConversionsRateDay(dayOds.getDeepConversionsRate());
-        adStatOfDay.setKeyPageUvDay(dayOds.getKeyPageUv());
-        adStatOfDay.setOrderCountDay(dayOds.getOrderCount());
-        adStatOfDay.setFirstDayOrderCountDay(dayOds.getFirstDayOrderCount());
-        adStatOfDay.setWebOrderCostDay(dayOds.getWebOrderCost());
-        adStatOfDay.setOrderRateDay(dayOds.getOrderRate());
-        adStatOfDay.setOrderAmountDay(dayOds.getOrderAmount());
-        adStatOfDay.setFirstDayOrderAmountDay(dayOds.getFirstDayOrderAmount());
-        adStatOfDay.setOrderUnitPriceDay(dayOds.getOrderUnitPrice());
-        adStatOfDay.setOrderRoiDay(dayOds.getOrderRoi());
-        adStatOfDay.setSignInCountDay(dayOds.getSignInCount());
-        adStatOfDay.setAddWishlistCountDay(dayOds.getAddWishlistCount());
-        adStatOfDay.setViewCommodityPageUvDay(dayOds.getViewCommodityPageUv());
-        adStatOfDay.setPageReservationCountDay(dayOds.getPageReservationCount());
-        adStatOfDay.setLeadsPurchaseUvDay(dayOds.getLeadsPurchaseUv());
-        adStatOfDay.setLeadsPurchaseCostDay(dayOds.getLeadsPurchaseCost());
-        adStatOfDay.setLeadsPurchaseRateDay(dayOds.getLeadsPurchaseRate());
-        adStatOfDay.setScanFollowCountDay(dayOds.getScanFollowCount());
-        adStatOfDay.setWechatAppRegisterUvDay(dayOds.getWechatAppRegisterUv());
-        adStatOfDay.setWechatMinigameRegisterCostDay(dayOds.getWechatMinigameRegisterCost());
-        adStatOfDay.setWechatMinigameRegisterRateDay(dayOds.getWechatMinigameRegisterRate());
-        adStatOfDay.setWechatMinigameArpuDay(dayOds.getWechatMinigameArpu());
-        adStatOfDay.setWechatMinigameRetentionCountDay(dayOds.getWechatMinigameRetentionCount());
-        adStatOfDay.setWechatMinigameCheckoutCountDay(dayOds.getWechatMinigameCheckoutCount());
-        adStatOfDay.setWechatMinigameCheckoutAmountDay(dayOds.getWechatMinigameCheckoutAmount());
-        adStatOfDay.setOfficialAccountFollowCountDay(dayOds.getOfficialAccountFollowCount());
-        adStatOfDay.setOfficialAccountFollowCostDay(dayOds.getOfficialAccountFollowCost());
-        adStatOfDay.setOfficialAccountFollowRateDay(dayOds.getOfficialAccountFollowRate());
-        adStatOfDay.setOfficialAccountRegisterUserCountDay(dayOds.getOfficialAccountRegisterUserCount());
-        adStatOfDay.setOfficialAccountRegisterRateDay(dayOds.getOfficialAccountRegisterRate());
-        adStatOfDay.setOfficialAccountRegisterCostDay(dayOds.getOfficialAccountRegisterCost());
-        adStatOfDay.setOfficialAccountRegisterAmountDay(dayOds.getOfficialAccountRegisterAmount());
-        adStatOfDay.setOfficialAccountRegisterRoiDay(dayOds.getOfficialAccountRegisterRoi());
-        adStatOfDay.setOfficialAccountApplyCountDay(dayOds.getOfficialAccountApplyCount());
-        adStatOfDay.setOfficialAccountApplyUserCountDay(dayOds.getOfficialAccountApplyUserCount());
-        adStatOfDay.setOfficialAccountApplyRateDay(dayOds.getOfficialAccountApplyRate());
-        adStatOfDay.setOfficialAccountApplyCostDay(dayOds.getOfficialAccountApplyCost());
-        adStatOfDay.setOfficialAccountApplyAmountDay(dayOds.getOfficialAccountApplyAmount());
-        adStatOfDay.setOfficialAccountApplyRoiDay(dayOds.getOfficialAccountApplyRoi());
-        adStatOfDay.setOfficialAccountOrderCountDay(dayOds.getOfficialAccountOrderCount());
-        adStatOfDay.setOfficialAccountFirstDayOrderCountDay(dayOds.getOfficialAccountFirstDayOrderCount());
-        adStatOfDay.setOfficialAccountOrderUserCountDay(dayOds.getOfficialAccountOrderUserCount());
-        adStatOfDay.setOfficialAccountOrderRateDay(dayOds.getOfficialAccountOrderRate());
-        adStatOfDay.setOfficialAccountOrderCostDay(dayOds.getOfficialAccountOrderCost());
-        adStatOfDay.setOfficialAccountOrderAmountDay(dayOds.getOfficialAccountOrderAmount());
-        adStatOfDay.setOfficialAccountFirstDayOrderAmountDay(dayOds.getOfficialAccountFirstDayOrderAmount());
-        adStatOfDay.setOfficialAccountOrderRoiDay(dayOds.getOfficialAccountOrderRoi());
-        adStatOfDay.setOfficialAccountConsultCountDay(dayOds.getOfficialAccountConsultCount());
-        adStatOfDay.setOfficialAccountReaderCountDay(dayOds.getOfficialAccountReaderCount());
-        adStatOfDay.setOfficialAccountCreditApplyUserCountDay(dayOds.getOfficialAccountCreditApplyUserCount());
-        adStatOfDay.setOfficialAccountCreditUserCountDay(dayOds.getOfficialAccountCreditUserCount());
-        adStatOfDay.setForwardCountDay(dayOds.getForwardCount());
-        adStatOfDay.setForwardUserCountDay(dayOds.getForwardUserCount());
-        adStatOfDay.setNoInterestCountDay(dayOds.getNoInterestCount());
-        return adStatOfDay;
-    }
-
     /**
      * 聚合
      *

+ 73 - 73
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfHourDWD.java

@@ -1200,80 +1200,80 @@ public class AdStatOfHourDWD {
     @SerializedName("no_interest_count_hour")
     private Long noInterestCountHour;
 
-    public static AdStatOfHourDWD byODS(AdDataOfHourODS adOds) {
+    public static AdStatOfHourDWD byODS(AdDataOfHourODS adODS) {
         AdStatOfHourDWD adStatOfHour = new AdStatOfHourDWD();
-        adStatOfHour.setStatDay(adOds.getStatDay());
-        adStatOfHour.setHour(adOds.getHour());
-        adStatOfHour.setAccountId(adOds.getAccountId());
-        adStatOfHour.setCampaignId(adOds.getCampaignId());
-        adStatOfHour.setAgencyAccountId(adOds.getAgencyAccountId());
-        adStatOfHour.setWechatAccountId(adOds.getWechatAccountId());
-        adStatOfHour.setWechatAgencyId(adOds.getWechatAgencyId());
-        adStatOfHour.setAdgroupId(adOds.getAdgroupId());
-        adStatOfHour.setAdId(adOds.getAdId());
-        adStatOfHour.setCostDeviationRateHour(adOds.getCostDeviationRate());
-        adStatOfHour.setCostHour(adOds.getCost());
-        adStatOfHour.setCompensationAmountHour(adOds.getCompensationAmount());
-        adStatOfHour.setViewCountHour(adOds.getViewCount());
-        adStatOfHour.setThousandDisplayPriceHour(adOds.getThousandDisplayPrice());
-        adStatOfHour.setAvgViewPerUserHour(adOds.getAvgViewPerUser());
-        adStatOfHour.setValidClickCountHour(adOds.getValidClickCount());
-        adStatOfHour.setCtrHour(adOds.getCtr());
-        adStatOfHour.setCpcHour(adOds.getCpc());
-        adStatOfHour.setValuableClickCountHour(adOds.getValuableClickCount());
-        adStatOfHour.setValuableClickRateHour(adOds.getValuableClickRate());
-        adStatOfHour.setValuableClickCostHour(adOds.getValuableClickCost());
-        adStatOfHour.setConversionsCountHour(adOds.getConversionsCount());
-        adStatOfHour.setConversionsCostHour(adOds.getConversionsCost());
-        adStatOfHour.setConversionsRateHour(adOds.getConversionsRate());
-        adStatOfHour.setDeepConversionsCountHour(adOds.getDeepConversionsCount());
-        adStatOfHour.setDeepConversionsCostHour(adOds.getDeepConversionsCost());
-        adStatOfHour.setDeepConversionsRateHour(adOds.getDeepConversionsRate());
-        adStatOfHour.setOrderCountHour(adOds.getOrderCount());
-        adStatOfHour.setFirstDayOrderCountHour(adOds.getFirstDayOrderCount());
-        adStatOfHour.setWebOrderCostHour(adOds.getWebOrderCost());
-        adStatOfHour.setOrderRateHour(adOds.getOrderRate());
-        adStatOfHour.setOrderAmountHour(adOds.getOrderAmount());
-        adStatOfHour.setFirstDayOrderAmountHour(adOds.getFirstDayOrderAmount());
-        adStatOfHour.setOrderUnitPriceHour(adOds.getOrderUnitPrice());
-        adStatOfHour.setOrderRoiHour(adOds.getOrderRoi());
-        adStatOfHour.setSignInCountHour(adOds.getSignInCount());
-        adStatOfHour.setScanFollowCountHour(adOds.getScanFollowCount());
-        adStatOfHour.setWechatAppRegisterUvHour(adOds.getWechatAppRegisterUv());
-        adStatOfHour.setWechatMinigameRegisterCostHour(adOds.getWechatMinigameRegisterCost());
-        adStatOfHour.setWechatMinigameRegisterRateHour(adOds.getWechatMinigameRegisterRate());
-        adStatOfHour.setWechatMinigameArpuHour(adOds.getWechatMinigameArpu());
-        adStatOfHour.setWechatMinigameRetentionCountHour(adOds.getWechatMinigameRetentionCount());
-        adStatOfHour.setWechatMinigameCheckoutCountHour(adOds.getWechatMinigameCheckoutCount());
-        adStatOfHour.setWechatMinigameCheckoutAmountHour(adOds.getWechatMinigameCheckoutAmount());
-        adStatOfHour.setOfficialAccountFollowCountHour(adOds.getOfficialAccountFollowCount());
-        adStatOfHour.setOfficialAccountFollowRateHour(adOds.getOfficialAccountFollowRate());
-        adStatOfHour.setOfficialAccountRegisterUserCountHour(adOds.getOfficialAccountRegisterUserCount());
-        adStatOfHour.setOfficialAccountRegisterRateHour(adOds.getOfficialAccountRegisterRate());
-        adStatOfHour.setOfficialAccountRegisterCostHour(adOds.getOfficialAccountRegisterCost());
-        adStatOfHour.setOfficialAccountRegisterAmountHour(adOds.getOfficialAccountRegisterAmount());
-        adStatOfHour.setOfficialAccountRegisterRoiHour(adOds.getOfficialAccountRegisterRoi());
-        adStatOfHour.setOfficialAccountApplyCountHour(adOds.getOfficialAccountApplyCount());
-        adStatOfHour.setOfficialAccountApplyUserCountHour(adOds.getOfficialAccountApplyUserCount());
-        adStatOfHour.setOfficialAccountApplyRateHour(adOds.getOfficialAccountApplyRate());
-        adStatOfHour.setOfficialAccountApplyCostHour(adOds.getOfficialAccountApplyCost());
-        adStatOfHour.setOfficialAccountApplyAmountHour(adOds.getOfficialAccountApplyAmount());
-        adStatOfHour.setOfficialAccountApplyRoiHour(adOds.getOfficialAccountApplyRoi());
-        adStatOfHour.setOfficialAccountOrderCountHour(adOds.getOfficialAccountOrderCount());
-        adStatOfHour.setOfficialAccountFirstDayOrderCountHour(adOds.getOfficialAccountFirstDayOrderCount());
-        adStatOfHour.setOfficialAccountOrderUserCountHour(adOds.getOfficialAccountOrderUserCount());
-        adStatOfHour.setOfficialAccountOrderRateHour(adOds.getOfficialAccountOrderRate());
-        adStatOfHour.setOfficialAccountOrderCostHour(adOds.getOfficialAccountOrderCost());
-        adStatOfHour.setOfficialAccountOrderAmountHour(adOds.getOfficialAccountOrderAmount());
-        adStatOfHour.setOfficialAccountFirstDayOrderAmountHour(adOds.getOfficialAccountFirstDayOrderAmount());
-        adStatOfHour.setOfficialAccountOrderRoiHour(adOds.getOfficialAccountOrderRoi());
-        adStatOfHour.setOfficialAccountConsultCountHour(adOds.getOfficialAccountConsultCount());
-        adStatOfHour.setOfficialAccountReaderCountHour(adOds.getOfficialAccountReaderCount());
-        adStatOfHour.setOfficialAccountCreditApplyUserCountHour(adOds.getOfficialAccountCreditApplyUserCount());
-        adStatOfHour.setOfficialAccountCreditUserCountHour(adOds.getOfficialAccountCreditUserCount());
-        adStatOfHour.setForwardCountHour(adOds.getForwardCount());
-        adStatOfHour.setForwardUserCountHour(adOds.getForwardUserCount());
-        adStatOfHour.setNoInterestCountHour(adOds.getNoInterestCount());
+        adStatOfHour.setStatDay(adODS.getStatDay());
+        adStatOfHour.setHour(adODS.getHour());
+        adStatOfHour.setAccountId(adODS.getAccountId());
+        adStatOfHour.setCampaignId(adODS.getCampaignId());
+        adStatOfHour.setAgencyAccountId(adODS.getAgencyAccountId());
+        adStatOfHour.setWechatAccountId(adODS.getWechatAccountId());
+        adStatOfHour.setWechatAgencyId(adODS.getWechatAgencyId());
+        adStatOfHour.setAdgroupId(adODS.getAdgroupId());
+        adStatOfHour.setAdId(adODS.getAdId());
+        adStatOfHour.setCostDeviationRateHour(adODS.getCostDeviationRate());
+        adStatOfHour.setCostHour(adODS.getCost());
+        adStatOfHour.setCompensationAmountHour(adODS.getCompensationAmount());
+        adStatOfHour.setViewCountHour(adODS.getViewCount());
+        adStatOfHour.setThousandDisplayPriceHour(adODS.getThousandDisplayPrice());
+        adStatOfHour.setAvgViewPerUserHour(adODS.getAvgViewPerUser());
+        adStatOfHour.setValidClickCountHour(adODS.getValidClickCount());
+        adStatOfHour.setCtrHour(adODS.getCtr());
+        adStatOfHour.setCpcHour(adODS.getCpc());
+        adStatOfHour.setValuableClickCountHour(adODS.getValuableClickCount());
+        adStatOfHour.setValuableClickRateHour(adODS.getValuableClickRate());
+        adStatOfHour.setValuableClickCostHour(adODS.getValuableClickCost());
+        adStatOfHour.setConversionsCountHour(adODS.getConversionsCount());
+        adStatOfHour.setConversionsCostHour(adODS.getConversionsCost());
+        adStatOfHour.setConversionsRateHour(adODS.getConversionsRate());
+        adStatOfHour.setDeepConversionsCountHour(adODS.getDeepConversionsCount());
+        adStatOfHour.setDeepConversionsCostHour(adODS.getDeepConversionsCost());
+        adStatOfHour.setDeepConversionsRateHour(adODS.getDeepConversionsRate());
+        adStatOfHour.setOrderCountHour(adODS.getOrderCount());
+        adStatOfHour.setFirstDayOrderCountHour(adODS.getFirstDayOrderCount());
+        adStatOfHour.setWebOrderCostHour(adODS.getWebOrderCost());
+        adStatOfHour.setOrderRateHour(adODS.getOrderRate());
+        adStatOfHour.setOrderAmountHour(adODS.getOrderAmount());
+        adStatOfHour.setFirstDayOrderAmountHour(adODS.getFirstDayOrderAmount());
+        adStatOfHour.setOrderUnitPriceHour(adODS.getOrderUnitPrice());
+        adStatOfHour.setOrderRoiHour(adODS.getOrderRoi());
+        adStatOfHour.setSignInCountHour(adODS.getSignInCount());
+        adStatOfHour.setScanFollowCountHour(adODS.getScanFollowCount());
+        adStatOfHour.setWechatAppRegisterUvHour(adODS.getWechatAppRegisterUv());
+        adStatOfHour.setWechatMinigameRegisterCostHour(adODS.getWechatMinigameRegisterCost());
+        adStatOfHour.setWechatMinigameRegisterRateHour(adODS.getWechatMinigameRegisterRate());
+        adStatOfHour.setWechatMinigameArpuHour(adODS.getWechatMinigameArpu());
+        adStatOfHour.setWechatMinigameRetentionCountHour(adODS.getWechatMinigameRetentionCount());
+        adStatOfHour.setWechatMinigameCheckoutCountHour(adODS.getWechatMinigameCheckoutCount());
+        adStatOfHour.setWechatMinigameCheckoutAmountHour(adODS.getWechatMinigameCheckoutAmount());
+        adStatOfHour.setOfficialAccountFollowCountHour(adODS.getOfficialAccountFollowCount());
+        adStatOfHour.setOfficialAccountFollowRateHour(adODS.getOfficialAccountFollowRate());
+        adStatOfHour.setOfficialAccountRegisterUserCountHour(adODS.getOfficialAccountRegisterUserCount());
+        adStatOfHour.setOfficialAccountRegisterRateHour(adODS.getOfficialAccountRegisterRate());
+        adStatOfHour.setOfficialAccountRegisterCostHour(adODS.getOfficialAccountRegisterCost());
+        adStatOfHour.setOfficialAccountRegisterAmountHour(adODS.getOfficialAccountRegisterAmount());
+        adStatOfHour.setOfficialAccountRegisterRoiHour(adODS.getOfficialAccountRegisterRoi());
+        adStatOfHour.setOfficialAccountApplyCountHour(adODS.getOfficialAccountApplyCount());
+        adStatOfHour.setOfficialAccountApplyUserCountHour(adODS.getOfficialAccountApplyUserCount());
+        adStatOfHour.setOfficialAccountApplyRateHour(adODS.getOfficialAccountApplyRate());
+        adStatOfHour.setOfficialAccountApplyCostHour(adODS.getOfficialAccountApplyCost());
+        adStatOfHour.setOfficialAccountApplyAmountHour(adODS.getOfficialAccountApplyAmount());
+        adStatOfHour.setOfficialAccountApplyRoiHour(adODS.getOfficialAccountApplyRoi());
+        adStatOfHour.setOfficialAccountOrderCountHour(adODS.getOfficialAccountOrderCount());
+        adStatOfHour.setOfficialAccountFirstDayOrderCountHour(adODS.getOfficialAccountFirstDayOrderCount());
+        adStatOfHour.setOfficialAccountOrderUserCountHour(adODS.getOfficialAccountOrderUserCount());
+        adStatOfHour.setOfficialAccountOrderRateHour(adODS.getOfficialAccountOrderRate());
+        adStatOfHour.setOfficialAccountOrderCostHour(adODS.getOfficialAccountOrderCost());
+        adStatOfHour.setOfficialAccountOrderAmountHour(adODS.getOfficialAccountOrderAmount());
+        adStatOfHour.setOfficialAccountFirstDayOrderAmountHour(adODS.getOfficialAccountFirstDayOrderAmount());
+        adStatOfHour.setOfficialAccountOrderRoiHour(adODS.getOfficialAccountOrderRoi());
+        adStatOfHour.setOfficialAccountConsultCountHour(adODS.getOfficialAccountConsultCount());
+        adStatOfHour.setOfficialAccountReaderCountHour(adODS.getOfficialAccountReaderCount());
+        adStatOfHour.setOfficialAccountCreditApplyUserCountHour(adODS.getOfficialAccountCreditApplyUserCount());
+        adStatOfHour.setOfficialAccountCreditUserCountHour(adODS.getOfficialAccountCreditUserCount());
+        adStatOfHour.setForwardCountHour(adODS.getForwardCount());
+        adStatOfHour.setForwardUserCountHour(adODS.getForwardUserCount());
+        adStatOfHour.setNoInterestCountHour(adODS.getNoInterestCount());
         return adStatOfHour;
     }
 

+ 765 - 3
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfMinuteDWD.java

@@ -1,21 +1,27 @@
 package flink.zanxiangnet.ad.monitoring.pojo.entity;
 
 import com.google.gson.annotations.SerializedName;
+import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeColumn;
+import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeTable;
 import lombok.Data;
+import org.springframework.beans.BeanUtils;
 
-import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
 
 /**
  * 广告维度的小时统计数据
  */
 @Data
+@MaxComputeTable("ad_stat_of_minute_dwd")
 public class AdStatOfMinuteDWD {
 
     /**
      * 统计的日期(用于 MaxCompute分区)
      */
+    @MaxComputeColumn(isPartitioned = true)
     @SerializedName("stat_day")
-    private LocalDate statDay;
+    private String statDay;
 
     /**
      * 统计的小时
@@ -71,6 +77,9 @@ public class AdStatOfMinuteDWD {
     @SerializedName("ad_id")
     private Long adId;
 
+    @SerializedName("create_time")
+    private Date createTime;
+
     /**
      * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
      */
@@ -1473,7 +1482,7 @@ public class AdStatOfMinuteDWD {
      * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
      */
     @SerializedName("official_account_credit_apply_user_count_day")
-    private Long officialAccountCreditApplyUserCountTotalDay;
+    private Long officialAccountCreditApplyUserCountDay;
 
     /**
      * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
@@ -1582,4 +1591,757 @@ public class AdStatOfMinuteDWD {
      */
     @SerializedName("no_interest_count_minute")
     private Long noInterestCountMinute;
+
+    /**
+     * 聚合
+     *
+     * @param beforeYesterdayDayDWD 广告前天(包括前天)聚合的天数据(用来计算总数据)
+     * @param yesterdayMinuteDWD    昨天聚合的数据
+     * @param todayODSList          当前待聚合的数据(当天数据列表)
+     * @param statODS
+     * @return
+     */
+    public static AdStatOfMinuteDWD reduce(AdStatOfDayDWD beforeYesterdayDayDWD, AdStatOfMinuteDWD yesterdayMinuteDWD, List<AdDataOfMinuteODS> todayODSList, AdDataOfMinuteODS statODS, AdStatOfMinuteDWD lastMinuteDWD, long createTime) {
+        AdStatOfMinuteDWD result = new AdStatOfMinuteDWD();
+        BeanUtils.copyProperties(statODS, result);
+        result = initValue(result);
+        result.setCreateTime(new Date(createTime));
+        // 填充小时数据
+        result.setCostDeviationRateHour(statODS.getCostDeviationRate());
+        result.setCostHour(statODS.getCost());
+        result.setCompensationAmountHour(statODS.getCompensationAmount());
+        result.setViewCountHour(statODS.getViewCount());
+        result.setThousandDisplayPriceHour(statODS.getThousandDisplayPrice());
+        result.setAvgViewPerUserHour(statODS.getAvgViewPerUser());
+        result.setValidClickCountHour(statODS.getValidClickCount());
+        result.setCtrHour(statODS.getCtr());
+        result.setCpcHour(statODS.getCpc());
+        result.setValuableClickCountHour(statODS.getValuableClickCount());
+        result.setValuableClickRateHour(statODS.getValuableClickRate());
+        result.setValuableClickCostHour(statODS.getValuableClickCost());
+        result.setConversionsCountHour(statODS.getConversionsCount());
+        result.setConversionsCostHour(statODS.getConversionsCost());
+        result.setConversionsRateHour(statODS.getConversionsRate());
+        result.setDeepConversionsCountHour(statODS.getDeepConversionsCount());
+        result.setDeepConversionsCostHour(statODS.getDeepConversionsCost());
+        result.setDeepConversionsRateHour(statODS.getDeepConversionsRate());
+        result.setOrderCountHour(statODS.getOrderCount());
+        result.setFirstDayOrderCountHour(statODS.getFirstDayOrderCount());
+        result.setWebOrderCostHour(statODS.getWebOrderCost());
+        result.setOrderRateHour(statODS.getOrderRate());
+        result.setOrderAmountHour(statODS.getOrderAmount());
+        result.setFirstDayOrderAmountHour(statODS.getFirstDayOrderAmount());
+        result.setOrderUnitPriceHour(statODS.getOrderUnitPrice());
+        result.setOrderRoiHour(statODS.getOrderRoi());
+        result.setSignInCountHour(statODS.getSignInCount());
+        result.setScanFollowCountHour(statODS.getScanFollowCount());
+        result.setWechatAppRegisterUvHour(statODS.getWechatAppRegisterUv());
+        result.setWechatMinigameRegisterCostHour(statODS.getWechatMinigameRegisterCost());
+        result.setWechatMinigameRegisterRateHour(statODS.getWechatMinigameRegisterRate());
+        result.setWechatMinigameArpuHour(statODS.getWechatMinigameArpu());
+        result.setWechatMinigameRetentionCountHour(statODS.getWechatMinigameRetentionCount());
+        result.setWechatMinigameCheckoutCountHour(statODS.getWechatMinigameCheckoutCount());
+        result.setWechatMinigameCheckoutAmountHour(statODS.getWechatMinigameCheckoutAmount());
+        result.setOfficialAccountFollowCountHour(statODS.getOfficialAccountFollowCount());
+        result.setOfficialAccountFollowRateHour(statODS.getOfficialAccountFollowRate());
+        result.setOfficialAccountRegisterUserCountHour(statODS.getOfficialAccountRegisterUserCount());
+        result.setOfficialAccountRegisterRateHour(statODS.getOfficialAccountRegisterRate());
+        result.setOfficialAccountRegisterCostHour(statODS.getOfficialAccountRegisterCost());
+        result.setOfficialAccountRegisterAmountHour(statODS.getOfficialAccountRegisterAmount());
+        result.setOfficialAccountRegisterRoiHour(statODS.getOfficialAccountRegisterRoi());
+        result.setOfficialAccountApplyCountHour(statODS.getOfficialAccountApplyCount());
+        result.setOfficialAccountApplyUserCountHour(statODS.getOfficialAccountApplyUserCount());
+        result.setOfficialAccountApplyRateHour(statODS.getOfficialAccountApplyRate());
+        result.setOfficialAccountApplyCostHour(statODS.getOfficialAccountApplyCost());
+        result.setOfficialAccountApplyAmountHour(statODS.getOfficialAccountApplyAmount());
+        result.setOfficialAccountApplyRoiHour(statODS.getOfficialAccountApplyRoi());
+        result.setOfficialAccountOrderCountHour(statODS.getOfficialAccountOrderCount());
+        result.setOfficialAccountFirstDayOrderCountHour(statODS.getOfficialAccountFirstDayOrderCount());
+        result.setOfficialAccountOrderUserCountHour(statODS.getOfficialAccountOrderUserCount());
+        result.setOfficialAccountOrderRateHour(statODS.getOfficialAccountOrderRate());
+        result.setOfficialAccountOrderCostHour(statODS.getOfficialAccountOrderCost());
+        result.setOfficialAccountOrderAmountHour(statODS.getOfficialAccountOrderAmount());
+        result.setOfficialAccountFirstDayOrderAmountHour(statODS.getOfficialAccountFirstDayOrderAmount());
+        result.setOfficialAccountOrderRoiHour(statODS.getOfficialAccountOrderRoi());
+        result.setOfficialAccountConsultCountHour(statODS.getOfficialAccountConsultCount());
+        result.setOfficialAccountReaderCountHour(statODS.getOfficialAccountReaderCount());
+        result.setOfficialAccountCreditApplyUserCountHour(statODS.getOfficialAccountCreditApplyUserCount());
+        result.setOfficialAccountCreditUserCountHour(statODS.getOfficialAccountCreditUserCount());
+        result.setForwardCountHour(statODS.getForwardCount());
+        result.setForwardUserCountHour(statODS.getForwardUserCount());
+        result.setNoInterestCountHour(statODS.getNoInterestCount());
+        // 聚合当天的数据
+        for (AdDataOfMinuteODS todayODS : todayODSList) {
+            result.setCostDeviationRateDay(result.getCostDeviationRateDay() + todayODS.getCostDeviationRate());
+            result.setCostDay(result.getCostDay() + todayODS.getCost());
+            result.setCompensationAmountDay(result.getCompensationAmountDay() + todayODS.getCompensationAmount());
+            result.setViewCountDay(result.getViewCountDay() + todayODS.getViewCount());
+            // 总消耗 / 总曝光
+            result.setThousandDisplayPriceDay(result.getViewCountDay() == 0 ? 0 : (result.getCostDay() / result.getViewCountDay() * 1000));
+            result.setValidClickCountDay(result.getValidClickCountDay() + todayODS.getValidClickCount());
+            // 广告点击次数 / 广告曝光次数
+            result.setCtrDay(result.getViewCountDay() == 0 ? 0.0 : result.getValidClickCountDay() / result.getViewCountDay());
+            // 广告花费/广告点击次数
+            result.setCpcDay(result.getValidClickCountDay() == 0 ? 0 : result.getCostDay() / result.getValidClickCountDay());
+            result.setValuableClickCountDay(result.getValuableClickCountDay() + todayODS.getValuableClickCount());
+            // 广告可转化点击次数/广告曝光次数
+            result.setValuableClickRateDay(result.getViewCountDay() == 0 ? 0.0 : result.getValuableClickCountDay() / result.getViewCountDay());
+            // 广告花费/可转化点击次数
+            result.setValuableClickCostDay(result.getValuableClickCountDay() == 0 ? 0 : result.getCostDay() / result.getValuableClickCountDay());
+            result.setConversionsCountDay(result.getConversionsCountDay() + todayODS.getConversionsCount());
+            // 广告花费/转化目标量
+            result.setConversionsCostDay(result.getConversionsCountDay() == 0 ? 0 : result.getCostDay() / result.getConversionsCountDay());
+            // 公众号:转化目标量/点击次数。
+            result.setConversionsRateDay(result.getValidClickCountDay() == 0 ? 0.0 : result.getConversionsCountDay() / result.getValidClickCountDay());
+            result.setDeepConversionsCountDay(result.getDeepConversionsCountDay() + todayODS.getDeepConversionsCount());
+            // 广告花费/深度转化目标量
+            result.setDeepConversionsCostDay(result.getDeepConversionsCountDay() == 0 ? 0 : result.getCostDay() / result.getDeepConversionsCountDay());
+            // 深度转化目标量/可转化点击次数
+            result.setDeepConversionsRateDay(result.getValuableClickCountDay() == 0 ? 0.0 : result.getDeepConversionsCountDay() / result.getValuableClickCountDay());
+            result.setOrderCountDay(result.getOrderCountDay() + todayODS.getOrderCount());
+            result.setFirstDayOrderCountDay(result.getFirstDayOrderCountDay() + todayODS.getFirstDayOrderCount());
+            // 广告花费/下单量
+            result.setWebOrderCostDay(result.getOrderCountDay() == 0 ? 0 : result.getCostDay() / result.getOrderCountDay());
+            // 下单量/点击次数
+            result.setOrderRateDay(result.getValidClickCountDay() == 0 ? 0.0 : result.getOrderCountDay() / result.getValidClickCountDay());
+            result.setOrderAmountDay(result.getOrderAmountDay() + todayODS.getOrderAmount());
+            result.setFirstDayOrderAmountDay(result.getFirstDayOrderAmountDay() + todayODS.getFirstDayOrderAmount());
+            // 下单金额/下单量
+            result.setOrderUnitPriceDay(result.getOrderCountDay() == 0 ? 0 : result.getOrderAmountDay() / result.getOrderCountDay());
+            // 下单金额/广告花费
+            result.setOrderRoiDay(result.getCostDay() == 0 ? 0.0 : result.getOrderAmountDay() / result.getCostDay());
+            result.setSignInCountDay(result.getSignInCountDay() + todayODS.getSignInCount());
+            result.setScanFollowCountDay(result.getScanFollowCountDay() + todayODS.getScanFollowCount());
+            result.setWechatAppRegisterUvDay(result.getWechatAppRegisterUvDay() + todayODS.getWechatAppRegisterUv());
+            // 广告消耗 / 小游戏注册人数
+            result.setWechatMinigameRegisterCostDay(result.getWechatAppRegisterUvDay() == 0 ? 0 : result.getCostDay() / result.getWechatAppRegisterUvDay());
+            // 小游戏注册人数 / 广告点击次数
+            result.setWechatMinigameRegisterRateDay(result.getValidClickCountDay() == 0 ? 0.0 : result.getWechatAppRegisterUvDay() / result.getValidClickCountDay());
+            // 总收益 / 总人数
+            result.setWechatMinigameArpuDay(result.getWechatAppRegisterUvDay() == 0 ? 0.0 : result.getOrderAmountDay() / result.getWechatAppRegisterUvDay());
+            result.setWechatMinigameRetentionCountDay(result.getWechatMinigameRetentionCountDay() + todayODS.getWechatMinigameRetentionCount());
+            result.setWechatMinigameCheckoutCountDay(result.getWechatMinigameCheckoutCountDay() + todayODS.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutAmountDay(result.getWechatMinigameCheckoutAmountDay() + todayODS.getWechatMinigameCheckoutAmount());
+            result.setOfficialAccountFollowCountDay(result.getOfficialAccountFollowCountDay() + todayODS.getOfficialAccountFollowCount());
+            // 关注次数 / 点击次数
+            result.setOfficialAccountFollowRateDay(result.getValidClickCountDay() == 0 ? 0.0 : result.getOfficialAccountFollowCountDay() / result.getValidClickCountDay());
+            result.setOfficialAccountRegisterUserCountDay(result.getOfficialAccountRegisterUserCountDay() + todayODS.getOfficialAccountRegisterUserCount());
+            // 公众号内注册人数 / 公众号关注次数
+            result.setOfficialAccountRegisterRateDay(result.getOfficialAccountFollowCountDay() == 0 ? 0.0 : result.getOfficialAccountRegisterUserCountDay() / result.getOfficialAccountFollowCountDay());
+            // 广告消耗 / 广告注册人数
+            result.setOfficialAccountRegisterCostDay(result.getOfficialAccountRegisterUserCountDay() == 0 ? 0 : result.getCostDay() / result.getOfficialAccountRegisterUserCountDay());
+            result.setOfficialAccountRegisterAmountDay(result.getOfficialAccountRegisterAmountDay() + todayODS.getOfficialAccountRegisterAmount());
+            // 注册产生的订单金额累计/广告花费
+            result.setOfficialAccountRegisterRoiDay(result.getCostDay() == 0 ? 0 : result.getOfficialAccountRegisterAmountDay() / result.getCostDay());
+            result.setOfficialAccountApplyCountDay(result.getOfficialAccountApplyCountDay() + todayODS.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyUserCountDay(result.getOfficialAccountApplyUserCountDay() + todayODS.getOfficialAccountApplyUserCount());
+            // 公众号内填单的独立用户数/公众号关注次数
+            result.setOfficialAccountApplyRateDay(result.getOfficialAccountFollowCountDay() == 0 ? 0.0 : result.getOfficialAccountApplyUserCountDay() / result.getOfficialAccountFollowCountDay());
+            // 广告花费/广告产生的填单行为数量
+            result.setOfficialAccountApplyCostDay(result.getOfficialAccountApplyUserCountDay() == 0 ? 0 : result.getCostDay() / result.getOfficialAccountApplyUserCountDay());
+            result.setOfficialAccountApplyAmountDay(result.getOfficialAccountApplyAmountDay() + todayODS.getOfficialAccountApplyAmount());
+            // 填单产生的订单金额累计/广告花费
+            result.setOfficialAccountApplyRoiDay(result.getCostDay() == 0 ? 0 : result.getOfficialAccountApplyAmountDay() / result.getCostDay());
+            result.setOfficialAccountOrderCountDay(result.getOfficialAccountOrderCountDay() + todayODS.getOfficialAccountOrderCount());
+            result.setOfficialAccountFirstDayOrderCountDay(result.getOfficialAccountFirstDayOrderCountDay() + todayODS.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountOrderUserCountDay(result.getOfficialAccountOrderUserCountDay() + todayODS.getOfficialAccountOrderUserCount());
+            // 公众号内下单独立用户数(UV)/公众号关注次数
+            result.setOfficialAccountOrderRateDay(result.getOfficialAccountFollowCountDay() == 0 ? 0.0 : result.getOfficialAccountOrderUserCountDay() / result.getOfficialAccountFollowCountDay());
+            // 广告花费/广告产生的下单行为数量
+            result.setOfficialAccountOrderCostDay(result.getOfficialAccountOrderCountDay() == 0 ? 0 : result.getCostDay() / result.getOfficialAccountOrderCountDay());
+            result.setOfficialAccountOrderAmountDay(result.getOfficialAccountOrderAmountDay() + todayODS.getOfficialAccountOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountDay(result.getOfficialAccountFirstDayOrderAmountDay() + todayODS.getOfficialAccountFirstDayOrderAmount());
+            // 下单产生的订单金额累计/广告花费
+            result.setOfficialAccountOrderRoiDay(result.getCostDay() == 0 ? 0 : result.getOfficialAccountOrderAmountDay() / result.getCostDay());
+            result.setOfficialAccountConsultCountDay(result.getOfficialAccountConsultCountDay() + todayODS.getOfficialAccountConsultCount());
+            result.setOfficialAccountReaderCountDay(result.getOfficialAccountReaderCountDay() + todayODS.getOfficialAccountReaderCount());
+            result.setOfficialAccountCreditApplyUserCountDay(result.getOfficialAccountCreditApplyUserCountDay() + todayODS.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditUserCountDay(result.getOfficialAccountCreditUserCountDay() + todayODS.getOfficialAccountCreditUserCount());
+            result.setForwardCountDay(result.getForwardCountDay() + todayODS.getForwardCount());
+            result.setForwardUserCountDay(result.getForwardUserCountDay() + todayODS.getForwardUserCount());
+            result.setNoInterestCountDay(result.getNoInterestCountDay() + todayODS.getNoInterestCount());
+        }
+        // 填充总数据
+        if (beforeYesterdayDayDWD != null) {
+            result.setCostDeviationRateTotal(beforeYesterdayDayDWD.getCostDeviationRateTotal());
+            result.setCostTotal(beforeYesterdayDayDWD.getCostTotal());
+            result.setCompensationAmountTotal(beforeYesterdayDayDWD.getCompensationAmountTotal());
+            result.setViewCountTotal(beforeYesterdayDayDWD.getViewCountTotal());
+            result.setThousandDisplayPriceAll(beforeYesterdayDayDWD.getThousandDisplayPriceAll());
+            result.setAvgViewPerUserAll(beforeYesterdayDayDWD.getAvgViewPerUserAll());
+            result.setValidClickCountTotal(beforeYesterdayDayDWD.getValidClickCountTotal());
+            result.setCtrAll(beforeYesterdayDayDWD.getCtrAll());
+            result.setCpcAll(beforeYesterdayDayDWD.getCpcAll());
+            result.setValuableClickCountTotal(beforeYesterdayDayDWD.getValuableClickCountTotal());
+            result.setValuableClickRateAll(beforeYesterdayDayDWD.getValuableClickRateAll());
+            result.setValuableClickCostAll(beforeYesterdayDayDWD.getValuableClickCostAll());
+            result.setConversionsCountTotal(beforeYesterdayDayDWD.getConversionsCountTotal());
+            result.setConversionsCostAll(beforeYesterdayDayDWD.getConversionsCostAll());
+            result.setConversionsRateAll(beforeYesterdayDayDWD.getConversionsRateAll());
+            result.setDeepConversionsCountTotal(beforeYesterdayDayDWD.getDeepConversionsCountTotal());
+            result.setDeepConversionsCostAll(beforeYesterdayDayDWD.getDeepConversionsCostAll());
+            result.setDeepConversionsRateAll(beforeYesterdayDayDWD.getDeepConversionsRateAll());
+            result.setOrderCountTotal(beforeYesterdayDayDWD.getOrderCountTotal());
+            result.setFirstDayOrderCountTotal(beforeYesterdayDayDWD.getFirstDayOrderCountTotal());
+            result.setWebOrderCostAll(beforeYesterdayDayDWD.getWebOrderCostAll());
+            result.setOrderRateAll(beforeYesterdayDayDWD.getOrderRateAll());
+            result.setOrderAmountTotal(beforeYesterdayDayDWD.getOrderAmountTotal());
+            result.setFirstDayOrderAmountTotal(beforeYesterdayDayDWD.getFirstDayOrderAmountTotal());
+            result.setOrderUnitPriceAll(beforeYesterdayDayDWD.getOrderUnitPriceAll());
+            result.setOrderRoiAll(beforeYesterdayDayDWD.getOrderRoiAll());
+            result.setSignInCountTotal(beforeYesterdayDayDWD.getSignInCountTotal());
+            result.setScanFollowCountTotal(beforeYesterdayDayDWD.getScanFollowCountTotal());
+            result.setWechatAppRegisterUvTotal(beforeYesterdayDayDWD.getWechatAppRegisterUvTotal());
+            result.setWechatMinigameRegisterCostAll(beforeYesterdayDayDWD.getWechatMinigameRegisterCostAll());
+            result.setWechatMinigameRegisterRateAll(beforeYesterdayDayDWD.getWechatMinigameRegisterRateAll());
+            result.setWechatMinigameArpuAll(beforeYesterdayDayDWD.getWechatMinigameArpuAll());
+            result.setWechatMinigameRetentionCountTotal(beforeYesterdayDayDWD.getWechatMinigameRetentionCountTotal());
+            result.setWechatMinigameCheckoutCountTotal(beforeYesterdayDayDWD.getWechatMinigameCheckoutCountTotal());
+            result.setWechatMinigameCheckoutAmountTotal(beforeYesterdayDayDWD.getWechatMinigameCheckoutAmountTotal());
+            result.setOfficialAccountFollowCountTotal(beforeYesterdayDayDWD.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountFollowRateAll(beforeYesterdayDayDWD.getOfficialAccountFollowRateAll());
+            result.setOfficialAccountRegisterUserCountTotal(beforeYesterdayDayDWD.getOfficialAccountRegisterUserCountTotal());
+            result.setOfficialAccountRegisterRateAll(beforeYesterdayDayDWD.getOfficialAccountRegisterRateAll());
+            result.setOfficialAccountRegisterCostAll(beforeYesterdayDayDWD.getOfficialAccountRegisterCostAll());
+            result.setOfficialAccountRegisterAmountTotal(beforeYesterdayDayDWD.getOfficialAccountRegisterAmountTotal());
+            result.setOfficialAccountRegisterRoiAll(beforeYesterdayDayDWD.getOfficialAccountRegisterRoiAll());
+            result.setOfficialAccountApplyCountTotal(beforeYesterdayDayDWD.getOfficialAccountApplyCountTotal());
+            result.setOfficialAccountApplyUserCountTotal(beforeYesterdayDayDWD.getOfficialAccountApplyUserCountTotal());
+            result.setOfficialAccountApplyRateAll(beforeYesterdayDayDWD.getOfficialAccountApplyRateAll());
+            result.setOfficialAccountApplyCostAll(beforeYesterdayDayDWD.getOfficialAccountApplyCostAll());
+            result.setOfficialAccountApplyAmountTotal(beforeYesterdayDayDWD.getOfficialAccountApplyAmountTotal());
+            result.setOfficialAccountApplyRoiAll(beforeYesterdayDayDWD.getOfficialAccountApplyRoiAll());
+            result.setOfficialAccountOrderCountTotal(beforeYesterdayDayDWD.getOfficialAccountOrderCountTotal());
+            result.setOfficialAccountFirstDayOrderCountTotal(beforeYesterdayDayDWD.getOfficialAccountFirstDayOrderCountTotal());
+            result.setOfficialAccountOrderUserCountTotal(beforeYesterdayDayDWD.getOfficialAccountOrderUserCountTotal());
+            result.setOfficialAccountOrderRateAll(beforeYesterdayDayDWD.getOfficialAccountOrderRateAll());
+            result.setOfficialAccountOrderCostAll(beforeYesterdayDayDWD.getOfficialAccountOrderCostAll());
+            result.setOfficialAccountOrderAmountTotal(beforeYesterdayDayDWD.getOfficialAccountOrderAmountTotal());
+            result.setOfficialAccountFirstDayOrderAmountTotal(beforeYesterdayDayDWD.getOfficialAccountFirstDayOrderAmountTotal());
+            result.setOfficialAccountOrderRoiAll(beforeYesterdayDayDWD.getOfficialAccountOrderRoiAll());
+            result.setOfficialAccountConsultCountTotal(beforeYesterdayDayDWD.getOfficialAccountConsultCountTotal());
+            result.setOfficialAccountReaderCountTotal(beforeYesterdayDayDWD.getOfficialAccountReaderCountTotal());
+            result.setOfficialAccountCreditApplyUserCountTotal(beforeYesterdayDayDWD.getOfficialAccountCreditApplyUserCountTotal());
+            result.setOfficialAccountCreditUserCountTotal(beforeYesterdayDayDWD.getOfficialAccountCreditUserCountTotal());
+            result.setForwardCountTotal(beforeYesterdayDayDWD.getForwardCountTotal());
+            result.setForwardUserCountTotal(beforeYesterdayDayDWD.getForwardUserCountTotal());
+            result.setNoInterestCountTotal(beforeYesterdayDayDWD.getNoInterestCountTotal());
+        }
+        if (yesterdayMinuteDWD != null) {
+            result.setCostDeviationRateTotal(result.getCostDeviationRateTotal() + yesterdayMinuteDWD.getCostDeviationRateTotal());
+            result.setCostTotal(result.getCostTotal() + yesterdayMinuteDWD.getCostTotal());
+            result.setCompensationAmountTotal(result.getCompensationAmountTotal() + yesterdayMinuteDWD.getCompensationAmountTotal());
+            result.setViewCountTotal(result.getViewCountTotal() + yesterdayMinuteDWD.getCompensationAmountTotal());
+            result.setValidClickCountTotal(result.getValidClickCountTotal() + yesterdayMinuteDWD.getValidClickCountTotal());
+            result.setValuableClickCountTotal(result.getValuableClickCountTotal() + yesterdayMinuteDWD.getValuableClickCountTotal());
+            result.setConversionsCountTotal(result.getConversionsCountTotal() + yesterdayMinuteDWD.getConversionsCountTotal());
+            result.setDeepConversionsCountTotal(result.getDeepConversionsCountTotal() + yesterdayMinuteDWD.getDeepConversionsCountTotal());
+            result.setOrderCountTotal(result.getOrderCountTotal() + yesterdayMinuteDWD.getOrderCountTotal());
+            result.setFirstDayOrderCountTotal(result.getFirstDayOrderCountTotal() + yesterdayMinuteDWD.getFirstDayOrderCountTotal());
+            result.setOrderAmountTotal(result.getOrderAmountTotal() + yesterdayMinuteDWD.getOrderAmountTotal());
+            result.setFirstDayOrderAmountTotal(result.getFirstDayOrderAmountTotal() + yesterdayMinuteDWD.getFirstDayOrderAmountTotal());
+            result.setSignInCountTotal(result.getSignInCountTotal() + yesterdayMinuteDWD.getSignInCountTotal());
+            result.setScanFollowCountTotal(result.getScanFollowCountTotal() + yesterdayMinuteDWD.getScanFollowCountTotal());
+            result.setWechatAppRegisterUvTotal(result.getWechatAppRegisterUvTotal() + yesterdayMinuteDWD.getWechatAppRegisterUvTotal());
+            result.setWechatMinigameRetentionCountTotal(result.getWechatMinigameRetentionCountTotal() + yesterdayMinuteDWD.getWechatMinigameRetentionCountTotal());
+            result.setWechatMinigameCheckoutCountTotal(result.getWechatMinigameCheckoutCountTotal() + yesterdayMinuteDWD.getWechatMinigameCheckoutCountTotal());
+            result.setWechatMinigameCheckoutAmountTotal(result.getWechatMinigameCheckoutAmountTotal() + yesterdayMinuteDWD.getWechatMinigameCheckoutAmountTotal());
+            result.setOfficialAccountFollowCountTotal(result.getOfficialAccountFollowCountTotal() + yesterdayMinuteDWD.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountRegisterUserCountTotal(result.getOfficialAccountRegisterUserCountTotal() + yesterdayMinuteDWD.getOfficialAccountRegisterUserCountTotal());
+            result.setOfficialAccountRegisterAmountTotal(result.getOfficialAccountRegisterAmountTotal() + yesterdayMinuteDWD.getOfficialAccountRegisterAmountTotal());
+            result.setOfficialAccountApplyCountTotal(result.getOfficialAccountApplyCountTotal() + yesterdayMinuteDWD.getOfficialAccountApplyCountTotal());
+            result.setOfficialAccountApplyUserCountTotal(result.getOfficialAccountApplyUserCountTotal() + yesterdayMinuteDWD.getOfficialAccountApplyUserCountTotal());
+            result.setOfficialAccountApplyAmountTotal(result.getOfficialAccountApplyAmountTotal() + yesterdayMinuteDWD.getOfficialAccountApplyAmountTotal());
+            result.setOfficialAccountOrderCountTotal(result.getOfficialAccountOrderCountTotal() + yesterdayMinuteDWD.getOfficialAccountOrderCountTotal());
+            result.setOfficialAccountFirstDayOrderCountTotal(result.getOfficialAccountFirstDayOrderCountTotal() + yesterdayMinuteDWD.getOfficialAccountFirstDayOrderCountTotal());
+            result.setOfficialAccountOrderUserCountTotal(result.getOfficialAccountOrderUserCountTotal() + yesterdayMinuteDWD.getOfficialAccountOrderUserCountTotal());
+            result.setOfficialAccountOrderAmountTotal(result.getOfficialAccountOrderAmountTotal() + yesterdayMinuteDWD.getOfficialAccountOrderAmountTotal());
+            result.setOfficialAccountFirstDayOrderAmountTotal(result.getOfficialAccountFirstDayOrderAmountTotal() + yesterdayMinuteDWD.getOfficialAccountFirstDayOrderAmountTotal());
+            result.setOfficialAccountConsultCountTotal(result.getOfficialAccountConsultCountTotal() + yesterdayMinuteDWD.getOfficialAccountConsultCountTotal());
+            result.setOfficialAccountReaderCountTotal(result.getOfficialAccountReaderCountTotal() + yesterdayMinuteDWD.getOfficialAccountReaderCountTotal());
+            result.setOfficialAccountCreditApplyUserCountTotal(result.getOfficialAccountCreditApplyUserCountTotal() + yesterdayMinuteDWD.getOfficialAccountCreditApplyUserCountTotal());
+            result.setOfficialAccountCreditUserCountTotal(result.getOfficialAccountCreditUserCountTotal() + yesterdayMinuteDWD.getOfficialAccountCreditUserCountTotal());
+            result.setForwardCountTotal(result.getForwardCountTotal() + yesterdayMinuteDWD.getForwardCountTotal());
+            result.setForwardUserCountTotal(result.getForwardUserCountTotal() + yesterdayMinuteDWD.getForwardUserCountTotal());
+            result.setNoInterestCountTotal(result.getNoInterestCountTotal() + yesterdayMinuteDWD.getNoInterestCountTotal());
+        }
+        result.setCostDeviationRateTotal(result.getCostDeviationRateTotal() + result.getCostDeviationRateDay());
+        result.setCostTotal(result.getCostTotal() + result.getCostDay());
+        result.setCompensationAmountTotal(result.getCompensationAmountTotal() + result.getCompensationAmountDay());
+        result.setViewCountTotal(result.getViewCountTotal() + result.getCompensationAmountDay());
+        result.setValidClickCountTotal(result.getValidClickCountTotal() + result.getValidClickCountDay());
+        result.setValuableClickCountTotal(result.getValuableClickCountTotal() + result.getValuableClickCountDay());
+        result.setConversionsCountTotal(result.getConversionsCountTotal() + result.getConversionsCountDay());
+        result.setDeepConversionsCountTotal(result.getDeepConversionsCountTotal() + result.getDeepConversionsCountDay());
+        result.setOrderCountTotal(result.getOrderCountTotal() + result.getOrderCountDay());
+        result.setFirstDayOrderCountTotal(result.getFirstDayOrderCountTotal() + result.getFirstDayOrderCountDay());
+        result.setOrderAmountTotal(result.getOrderAmountTotal() + result.getOrderAmountDay());
+        result.setFirstDayOrderAmountTotal(result.getFirstDayOrderAmountTotal() + result.getFirstDayOrderAmountDay());
+        result.setSignInCountTotal(result.getSignInCountTotal() + result.getSignInCountDay());
+        result.setScanFollowCountTotal(result.getScanFollowCountTotal() + result.getScanFollowCountDay());
+        result.setWechatAppRegisterUvTotal(result.getWechatAppRegisterUvTotal() + result.getWechatAppRegisterUvDay());
+        result.setWechatMinigameRetentionCountTotal(result.getWechatMinigameRetentionCountTotal() + result.getWechatMinigameRetentionCountDay());
+        result.setWechatMinigameCheckoutCountTotal(result.getWechatMinigameCheckoutCountTotal() + result.getWechatMinigameCheckoutCountDay());
+        result.setWechatMinigameCheckoutAmountTotal(result.getWechatMinigameCheckoutAmountTotal() + result.getWechatMinigameCheckoutAmountDay());
+        result.setOfficialAccountFollowCountTotal(result.getOfficialAccountFollowCountTotal() + result.getOfficialAccountFollowCountDay());
+        result.setOfficialAccountRegisterUserCountTotal(result.getOfficialAccountRegisterUserCountTotal() + result.getOfficialAccountRegisterUserCountDay());
+        result.setOfficialAccountRegisterAmountTotal(result.getOfficialAccountRegisterAmountTotal() + result.getOfficialAccountRegisterAmountDay());
+        result.setOfficialAccountApplyCountTotal(result.getOfficialAccountApplyCountTotal() + result.getOfficialAccountApplyCountDay());
+        result.setOfficialAccountApplyUserCountTotal(result.getOfficialAccountApplyUserCountTotal() + result.getOfficialAccountApplyUserCountDay());
+        result.setOfficialAccountOrderCountTotal(result.getOfficialAccountOrderCountTotal() + result.getOfficialAccountOrderCountDay());
+        result.setOfficialAccountFirstDayOrderCountTotal(result.getOfficialAccountFirstDayOrderCountTotal() + result.getOfficialAccountFirstDayOrderCountDay());
+        result.setOfficialAccountOrderUserCountTotal(result.getOfficialAccountOrderUserCountTotal() + result.getOfficialAccountOrderUserCountDay());
+        result.setOfficialAccountApplyAmountTotal(result.getOfficialAccountApplyAmountTotal() + result.getOfficialAccountApplyAmountDay());
+        result.setOfficialAccountOrderAmountTotal(result.getOfficialAccountOrderAmountTotal() + result.getOfficialAccountOrderAmountDay());
+        result.setOfficialAccountFirstDayOrderAmountTotal(result.getOfficialAccountFirstDayOrderAmountTotal() + result.getOfficialAccountFirstDayOrderAmountDay());
+        result.setOfficialAccountConsultCountTotal(result.getOfficialAccountConsultCountTotal() + result.getOfficialAccountConsultCountDay());
+        result.setOfficialAccountReaderCountTotal(result.getOfficialAccountReaderCountTotal() + result.getOfficialAccountReaderCountDay());
+        result.setOfficialAccountCreditApplyUserCountTotal(result.getOfficialAccountCreditApplyUserCountTotal() + result.getOfficialAccountCreditApplyUserCountDay());
+        result.setOfficialAccountCreditUserCountTotal(result.getOfficialAccountCreditUserCountTotal() + result.getOfficialAccountCreditUserCountDay());
+        result.setForwardCountTotal(result.getForwardCountTotal() + result.getForwardCountDay());
+        result.setForwardUserCountTotal(result.getForwardUserCountTotal() + result.getForwardUserCountDay());
+        result.setNoInterestCountTotal(result.getNoInterestCountTotal() + result.getNoInterestCountDay());
+        // 总消耗 / 总曝光
+        result.setThousandDisplayPriceAll(result.getViewCountTotal() == 0 ? 0 : (result.getCostTotal() / result.getViewCountTotal() * 1000));
+        // 广告点击次数 / 广告曝光次数
+        result.setCtrAll(result.getViewCountTotal() == 0 ? 0.0 : result.getValidClickCountTotal() / result.getViewCountTotal());
+        // 广告花费/广告点击次数
+        result.setCpcAll(result.getValidClickCountTotal() == 0 ? 0 : result.getCostTotal() / result.getValidClickCountTotal());
+        // 广告可转化点击次数/广告曝光次数
+        result.setValuableClickRateAll(result.getViewCountTotal() == 0 ? 0.0 : result.getValuableClickCountTotal() / result.getViewCountTotal());
+        // 广告花费/可转化点击次数
+        result.setValuableClickCostAll(result.getValuableClickCountTotal() == 0 ? 0 : result.getCostTotal() / result.getValuableClickCountTotal());
+        // 广告花费/转化目标量
+        result.setConversionsCostAll(result.getConversionsCountTotal() == 0 ? 0 : result.getCostTotal() / result.getConversionsCountTotal());
+        // 公众号:转化目标量/点击次数。
+        result.setConversionsRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getConversionsCountTotal() / result.getValidClickCountTotal());
+        // 广告花费/深度转化目标量
+        result.setDeepConversionsCostAll(result.getDeepConversionsCountTotal() == 0 ? 0 : result.getCostTotal() / result.getDeepConversionsCountTotal());
+        // 深度转化目标量/可转化点击次数
+        result.setDeepConversionsRateAll(result.getValuableClickCountTotal() == 0 ? 0.0 : result.getDeepConversionsCountTotal() / result.getValuableClickCountTotal());
+        // 广告花费/下单量
+        result.setWebOrderCostAll(result.getOrderCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOrderCountTotal());
+        // 下单量/点击次数
+        result.setOrderRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getOrderCountTotal() / result.getValidClickCountTotal());
+        // 下单金额/下单量
+        result.setOrderUnitPriceAll(result.getOrderCountTotal() == 0 ? 0 : result.getOrderAmountTotal() / result.getOrderCountTotal());
+        // 下单金额/广告花费
+        result.setOrderRoiAll(result.getCostTotal() == 0 ? 0.0 : result.getOrderAmountTotal() / result.getCostTotal());
+        // 广告消耗 / 小游戏注册人数
+        result.setWechatMinigameRegisterCostAll(result.getWechatAppRegisterUvTotal() == 0 ? 0 : result.getCostTotal() / result.getWechatAppRegisterUvTotal());
+        // 小游戏注册人数 / 广告点击次数
+        result.setWechatMinigameRegisterRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getWechatAppRegisterUvTotal() / result.getValidClickCountTotal());
+        // 总收益 / 总人数
+        result.setWechatMinigameArpuAll(result.getWechatAppRegisterUvTotal() == 0 ? 0.0 : result.getOrderAmountTotal() / result.getWechatAppRegisterUvTotal());
+        // 关注次数 / 点击次数
+        result.setOfficialAccountFollowRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getOfficialAccountFollowCountTotal() / result.getValidClickCountTotal());
+        // 公众号内注册人数 / 公众号关注次数
+        result.setOfficialAccountRegisterRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountRegisterUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+        // 广告消耗 / 广告注册人数
+        result.setOfficialAccountRegisterCostAll(result.getOfficialAccountRegisterUserCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountRegisterUserCountTotal());
+        // 注册产生的订单金额累计/广告花费
+        result.setOfficialAccountRegisterRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountRegisterAmountTotal() / result.getCostTotal());
+        // 公众号内填单的独立用户数/公众号关注次数
+        result.setOfficialAccountApplyRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountApplyUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+        // 广告花费/广告产生的填单行为数量
+        result.setOfficialAccountApplyCostAll(result.getOfficialAccountApplyUserCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountApplyUserCountTotal());
+        // 填单产生的订单金额累计/广告花费
+        result.setOfficialAccountApplyRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountApplyAmountTotal() / result.getCostTotal());
+        // 公众号内下单独立用户数(UV)/公众号关注次数
+        result.setOfficialAccountOrderRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountOrderUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+        // 广告花费/广告产生的下单行为数量
+        result.setOfficialAccountOrderCostAll(result.getOfficialAccountOrderCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountOrderCountTotal());
+        // 下单产生的订单金额累计/广告花费
+        result.setOfficialAccountOrderRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountOrderAmountTotal() / result.getCostTotal());
+
+        // 上一次聚合的 5分钟数据
+        if (lastMinuteDWD != null) {
+            if (lastMinuteDWD.getHour().equals(result.getHour())) {
+                result.setCostDeviationRateMinute(result.getCostDeviationRateHour() - lastMinuteDWD.getCostDeviationRateHour());
+                result.setCostMinute(result.getCostHour() - lastMinuteDWD.getCostHour());
+                result.setCompensationAmountMinute(result.getCompensationAmountHour() - lastMinuteDWD.getCompensationAmountHour());
+                result.setViewCountMinute(result.getViewCountHour() - lastMinuteDWD.getViewCountHour());
+                result.setThousandDisplayPriceMinute(result.getThousandDisplayPriceHour() - lastMinuteDWD.getThousandDisplayPriceHour());
+                result.setAvgViewPerUserMinute(result.getAvgViewPerUserHour() - lastMinuteDWD.getAvgViewPerUserHour());
+                result.setValidClickCountMinute(result.getValidClickCountHour() - lastMinuteDWD.getValidClickCountHour());
+                result.setCtrMinute(result.getCtrHour() - lastMinuteDWD.getCtrHour());
+                result.setCpcMinute(result.getCpcHour() - lastMinuteDWD.getCpcHour());
+                result.setValuableClickCountMinute(result.getValuableClickCountHour() - lastMinuteDWD.getValuableClickCountHour());
+                result.setValuableClickRateMinute(result.getValuableClickRateHour() - lastMinuteDWD.getValuableClickRateHour());
+                result.setValuableClickCostMinute(result.getValuableClickCostHour() - lastMinuteDWD.getValuableClickCostHour());
+                result.setConversionsCountMinute(result.getConversionsCountHour() - lastMinuteDWD.getConversionsCountHour());
+                result.setConversionsCostMinute(result.getConversionsCostHour() - lastMinuteDWD.getConversionsCostHour());
+                result.setConversionsRateMinute(result.getConversionsRateHour() - lastMinuteDWD.getConversionsRateHour());
+                result.setDeepConversionsCountMinute(result.getDeepConversionsCountHour() - lastMinuteDWD.getDeepConversionsCountHour());
+                result.setDeepConversionsCostMinute(result.getDeepConversionsCostHour() - lastMinuteDWD.getDeepConversionsCostHour());
+                result.setDeepConversionsRateMinute(result.getDeepConversionsRateHour() - lastMinuteDWD.getDeepConversionsRateHour());
+                result.setOrderCountMinute(result.getOrderCountHour() - lastMinuteDWD.getOrderCountHour());
+                result.setFirstDayOrderCountMinute(result.getFirstDayOrderCountHour() - lastMinuteDWD.getFirstDayOrderCountHour());
+                result.setWebOrderCostMinute(result.getWebOrderCostHour() - lastMinuteDWD.getWebOrderCostHour());
+                result.setOrderRateMinute(result.getOrderRateHour() - lastMinuteDWD.getOrderRateHour());
+                result.setOrderAmountMinute(result.getOrderAmountHour() - lastMinuteDWD.getOrderAmountHour());
+                result.setFirstDayOrderAmountMinute(result.getFirstDayOrderAmountHour() - lastMinuteDWD.getFirstDayOrderAmountHour());
+                result.setOrderUnitPriceMinute(result.getOrderUnitPriceHour() - lastMinuteDWD.getOrderUnitPriceHour());
+                result.setOrderRoiMinute(result.getOrderRoiHour() - lastMinuteDWD.getOrderRoiHour());
+                result.setSignInCountMinute(result.getSignInCountHour() - lastMinuteDWD.getSignInCountHour());
+                result.setScanFollowCountMinute(result.getScanFollowCountHour() - lastMinuteDWD.getScanFollowCountHour());
+                result.setWechatAppRegisterUvMinute(result.getWechatAppRegisterUvHour() - lastMinuteDWD.getWechatAppRegisterUvHour());
+                result.setWechatMinigameRegisterCostMinute(result.getWechatMinigameRegisterCostHour() - lastMinuteDWD.getWechatMinigameRegisterCostHour());
+                result.setWechatMinigameRegisterRateMinute(result.getWechatMinigameRegisterRateHour() - lastMinuteDWD.getWechatMinigameRegisterRateHour());
+                result.setWechatMinigameArpuMinute(result.getWechatMinigameArpuHour() - lastMinuteDWD.getWechatMinigameArpuHour());
+                result.setWechatMinigameRetentionCountMinute(result.getWechatMinigameRetentionCountHour() - lastMinuteDWD.getWechatMinigameRetentionCountHour());
+                result.setWechatMinigameCheckoutCountMinute(result.getWechatMinigameCheckoutCountHour() - lastMinuteDWD.getWechatMinigameCheckoutCountHour());
+                result.setWechatMinigameCheckoutAmountMinute(result.getWechatMinigameCheckoutAmountHour() - lastMinuteDWD.getWechatMinigameCheckoutAmountHour());
+                result.setOfficialAccountFollowCountMinute(result.getOfficialAccountFollowCountHour() - lastMinuteDWD.getOfficialAccountFollowCountHour());
+                result.setOfficialAccountFollowRateMinute(result.getOfficialAccountFollowRateHour() - lastMinuteDWD.getOfficialAccountFollowRateHour());
+                result.setOfficialAccountRegisterUserCountMinute(result.getOfficialAccountRegisterUserCountHour() - lastMinuteDWD.getOfficialAccountRegisterUserCountHour());
+                result.setOfficialAccountRegisterRateMinute(result.getOfficialAccountRegisterRateHour() - lastMinuteDWD.getOfficialAccountRegisterRateHour());
+                result.setOfficialAccountRegisterCostMinute(result.getOfficialAccountRegisterCostHour() - lastMinuteDWD.getOfficialAccountRegisterCostHour());
+                result.setOfficialAccountRegisterAmountMinute(result.getOfficialAccountRegisterAmountHour() - lastMinuteDWD.getOfficialAccountRegisterAmountHour());
+                result.setOfficialAccountRegisterRoiMinute(result.getOfficialAccountRegisterRoiHour() - lastMinuteDWD.getOfficialAccountRegisterRoiHour());
+                result.setOfficialAccountApplyCountMinute(result.getOfficialAccountApplyCountHour() - lastMinuteDWD.getOfficialAccountApplyCountHour());
+                result.setOfficialAccountApplyUserCountMinute(result.getOfficialAccountApplyUserCountHour() - lastMinuteDWD.getOfficialAccountApplyUserCountHour());
+                result.setOfficialAccountApplyRateMinute(result.getOfficialAccountApplyRateHour() - lastMinuteDWD.getOfficialAccountApplyRateHour());
+                result.setOfficialAccountApplyCostMinute(result.getOfficialAccountApplyCostHour() - lastMinuteDWD.getOfficialAccountApplyCostHour());
+                result.setOfficialAccountApplyAmountMinute(result.getOfficialAccountApplyAmountHour() - lastMinuteDWD.getOfficialAccountApplyAmountHour());
+                result.setOfficialAccountApplyRoiMinute(result.getOfficialAccountApplyRoiHour() - lastMinuteDWD.getOfficialAccountApplyRoiHour());
+                result.setOfficialAccountOrderCountMinute(result.getOfficialAccountOrderCountHour() - lastMinuteDWD.getOfficialAccountOrderCountHour());
+                result.setOfficialAccountFirstDayOrderCountMinute(result.getOfficialAccountFirstDayOrderCountHour() - lastMinuteDWD.getOfficialAccountFirstDayOrderCountHour());
+                result.setOfficialAccountOrderUserCountMinute(result.getOfficialAccountOrderUserCountHour() - lastMinuteDWD.getOfficialAccountOrderUserCountHour());
+                result.setOfficialAccountOrderRateMinute(result.getOfficialAccountOrderRateHour() - lastMinuteDWD.getOfficialAccountOrderRateHour());
+                result.setOfficialAccountOrderCostMinute(result.getOfficialAccountOrderCostHour() - lastMinuteDWD.getOfficialAccountOrderCostHour());
+                result.setOfficialAccountOrderAmountMinute(result.getOfficialAccountOrderAmountHour() - lastMinuteDWD.getOfficialAccountOrderAmountHour());
+                result.setOfficialAccountFirstDayOrderAmountMinute(result.getOfficialAccountFirstDayOrderAmountHour() - lastMinuteDWD.getOfficialAccountFirstDayOrderAmountHour());
+                result.setOfficialAccountOrderRoiMinute(result.getOfficialAccountOrderRoiHour() - lastMinuteDWD.getOfficialAccountOrderRoiHour());
+                result.setOfficialAccountConsultCountMinute(result.getOfficialAccountConsultCountHour() - lastMinuteDWD.getOfficialAccountConsultCountHour());
+                result.setOfficialAccountReaderCountMinute(result.getOfficialAccountReaderCountHour() - lastMinuteDWD.getOfficialAccountReaderCountHour());
+                result.setOfficialAccountCreditApplyUserCountMinute(result.getOfficialAccountCreditApplyUserCountHour() - lastMinuteDWD.getOfficialAccountCreditApplyUserCountHour());
+                result.setOfficialAccountCreditUserCountMinute(result.getOfficialAccountCreditUserCountHour() - lastMinuteDWD.getOfficialAccountCreditUserCountHour());
+                result.setForwardCountMinute(result.getForwardCountHour() - lastMinuteDWD.getForwardCountHour());
+                result.setForwardUserCountMinute(result.getForwardUserCountHour() - lastMinuteDWD.getForwardUserCountHour());
+                result.setNoInterestCountMinute(result.getNoInterestCountHour() - lastMinuteDWD.getNoInterestCountHour());
+            } else {
+                result.setCostDeviationRateMinute(statODS.getCostDeviationRate());
+                result.setCostMinute(statODS.getCost());
+                result.setCompensationAmountMinute(statODS.getCompensationAmount());
+                result.setViewCountMinute(statODS.getViewCount());
+                result.setThousandDisplayPriceMinute(statODS.getThousandDisplayPrice());
+                result.setAvgViewPerUserMinute(statODS.getAvgViewPerUser());
+                result.setValidClickCountMinute(statODS.getValidClickCount());
+                result.setCtrMinute(statODS.getCtr());
+                result.setCpcMinute(statODS.getCpc());
+                result.setValuableClickCountMinute(statODS.getValuableClickCount());
+                result.setValuableClickRateMinute(statODS.getValuableClickRate());
+                result.setValuableClickCostMinute(statODS.getValuableClickCost());
+                result.setConversionsCountMinute(statODS.getConversionsCount());
+                result.setConversionsCostMinute(statODS.getConversionsCost());
+                result.setConversionsRateMinute(statODS.getConversionsRate());
+                result.setDeepConversionsCountMinute(statODS.getDeepConversionsCount());
+                result.setDeepConversionsCostMinute(statODS.getDeepConversionsCost());
+                result.setDeepConversionsRateMinute(statODS.getDeepConversionsRate());
+                result.setOrderCountMinute(statODS.getOrderCount());
+                result.setFirstDayOrderCountMinute(statODS.getFirstDayOrderCount());
+                result.setWebOrderCostMinute(statODS.getWebOrderCost());
+                result.setOrderRateMinute(statODS.getOrderRate());
+                result.setOrderAmountMinute(statODS.getOrderAmount());
+                result.setFirstDayOrderAmountMinute(statODS.getFirstDayOrderAmount());
+                result.setOrderUnitPriceMinute(statODS.getOrderUnitPrice());
+                result.setOrderRoiMinute(statODS.getOrderRoi());
+                result.setSignInCountMinute(statODS.getSignInCount());
+                result.setScanFollowCountMinute(statODS.getScanFollowCount());
+                result.setWechatAppRegisterUvMinute(statODS.getWechatAppRegisterUv());
+                result.setWechatMinigameRegisterCostMinute(statODS.getWechatMinigameRegisterCost());
+                result.setWechatMinigameRegisterRateMinute(statODS.getWechatMinigameRegisterRate());
+                result.setWechatMinigameArpuMinute(statODS.getWechatMinigameArpu());
+                result.setWechatMinigameRetentionCountMinute(statODS.getWechatMinigameRetentionCount());
+                result.setWechatMinigameCheckoutCountMinute(statODS.getWechatMinigameCheckoutCount());
+                result.setWechatMinigameCheckoutAmountMinute(statODS.getWechatMinigameCheckoutAmount());
+                result.setOfficialAccountFollowCountMinute(statODS.getOfficialAccountFollowCount());
+                result.setOfficialAccountFollowRateMinute(statODS.getOfficialAccountFollowRate());
+                result.setOfficialAccountRegisterUserCountMinute(statODS.getOfficialAccountRegisterUserCount());
+                result.setOfficialAccountRegisterRateMinute(statODS.getOfficialAccountRegisterRate());
+                result.setOfficialAccountRegisterCostMinute(statODS.getOfficialAccountRegisterCost());
+                result.setOfficialAccountRegisterAmountMinute(statODS.getOfficialAccountRegisterAmount());
+                result.setOfficialAccountRegisterRoiMinute(statODS.getOfficialAccountRegisterRoi());
+                result.setOfficialAccountApplyCountMinute(statODS.getOfficialAccountApplyCount());
+                result.setOfficialAccountApplyUserCountMinute(statODS.getOfficialAccountApplyUserCount());
+                result.setOfficialAccountApplyRateMinute(statODS.getOfficialAccountApplyRate());
+                result.setOfficialAccountApplyCostMinute(statODS.getOfficialAccountApplyCost());
+                result.setOfficialAccountApplyAmountMinute(statODS.getOfficialAccountApplyAmount());
+                result.setOfficialAccountApplyRoiMinute(statODS.getOfficialAccountApplyRoi());
+                result.setOfficialAccountOrderCountMinute(statODS.getOfficialAccountOrderCount());
+                result.setOfficialAccountFirstDayOrderCountMinute(statODS.getOfficialAccountFirstDayOrderCount());
+                result.setOfficialAccountOrderUserCountMinute(statODS.getOfficialAccountOrderUserCount());
+                result.setOfficialAccountOrderRateMinute(statODS.getOfficialAccountOrderRate());
+                result.setOfficialAccountOrderCostMinute(statODS.getOfficialAccountOrderCost());
+                result.setOfficialAccountOrderAmountMinute(statODS.getOfficialAccountOrderAmount());
+                result.setOfficialAccountFirstDayOrderAmountMinute(statODS.getOfficialAccountFirstDayOrderAmount());
+                result.setOfficialAccountOrderRoiMinute(statODS.getOfficialAccountOrderRoi());
+                result.setOfficialAccountConsultCountMinute(statODS.getOfficialAccountConsultCount());
+                result.setOfficialAccountReaderCountMinute(statODS.getOfficialAccountReaderCount());
+                result.setOfficialAccountCreditApplyUserCountMinute(statODS.getOfficialAccountCreditApplyUserCount());
+                result.setOfficialAccountCreditUserCountMinute(statODS.getOfficialAccountCreditUserCount());
+                result.setForwardCountMinute(statODS.getForwardCount());
+                result.setForwardUserCountMinute(statODS.getForwardUserCount());
+                result.setNoInterestCountMinute(statODS.getNoInterestCount());
+            }
+        }
+        return result;
+    }
+
+    private static AdStatOfMinuteDWD initValue(AdStatOfMinuteDWD dwd) {
+        dwd.setCostDeviationRateTotal(0.0);
+        dwd.setCostDeviationRateDay(0.0);
+        dwd.setCostDeviationRateHour(0.0);
+        dwd.setCostDeviationRateMinute(0.0);
+        dwd.setCostTotal(0L);
+        dwd.setCostDay(0L);
+        dwd.setCostHour(0L);
+        dwd.setCostMinute(0L);
+        dwd.setCompensationAmountTotal(0L);
+        dwd.setCompensationAmountDay(0L);
+        dwd.setCompensationAmountHour(0L);
+        dwd.setCompensationAmountMinute(0L);
+        dwd.setViewCountTotal(0L);
+        dwd.setViewCountDay(0L);
+        dwd.setViewCountHour(0L);
+        dwd.setViewCountMinute(0L);
+        dwd.setThousandDisplayPriceAll(0L);
+        dwd.setThousandDisplayPriceDay(0L);
+        dwd.setThousandDisplayPriceHour(0L);
+        dwd.setThousandDisplayPriceMinute(0L);
+        dwd.setAvgViewPerUserAll(0.0);
+        dwd.setAvgViewPerUserDay(0.0);
+        dwd.setAvgViewPerUserHour(0.0);
+        dwd.setAvgViewPerUserMinute(0.0);
+        dwd.setValidClickCountTotal(0L);
+        dwd.setValidClickCountDay(0L);
+        dwd.setValidClickCountHour(0L);
+        dwd.setValidClickCountMinute(0L);
+        dwd.setCtrAll(0.0);
+        dwd.setCtrDay(0.0);
+        dwd.setCtrHour(0.0);
+        dwd.setCtrMinute(0.0);
+        dwd.setCpcAll(0L);
+        dwd.setCpcDay(0L);
+        dwd.setCpcHour(0L);
+        dwd.setCpcMinute(0L);
+        dwd.setValuableClickCountTotal(0L);
+        dwd.setValuableClickCountDay(0L);
+        dwd.setValuableClickCountHour(0L);
+        dwd.setValuableClickCountMinute(0L);
+        dwd.setValuableClickRateAll(0.0);
+        dwd.setValuableClickRateDay(0.0);
+        dwd.setValuableClickRateHour(0.0);
+        dwd.setValuableClickRateMinute(0.0);
+        dwd.setValuableClickCostAll(0L);
+        dwd.setValuableClickCostDay(0L);
+        dwd.setValuableClickCostHour(0L);
+        dwd.setValuableClickCostMinute(0L);
+        dwd.setConversionsCountTotal(0L);
+        dwd.setConversionsCountDay(0L);
+        dwd.setConversionsCountHour(0L);
+        dwd.setConversionsCountMinute(0L);
+        dwd.setConversionsCostAll(0L);
+        dwd.setConversionsCostDay(0L);
+        dwd.setConversionsCostHour(0L);
+        dwd.setConversionsCostMinute(0L);
+        dwd.setConversionsRateAll(0.0);
+        dwd.setConversionsRateDay(0.0);
+        dwd.setConversionsRateHour(0.0);
+        dwd.setConversionsRateMinute(0.0);
+        dwd.setDeepConversionsCountTotal(0L);
+        dwd.setDeepConversionsCountDay(0L);
+        dwd.setDeepConversionsCountHour(0L);
+        dwd.setDeepConversionsCountMinute(0L);
+        dwd.setDeepConversionsCostAll(0L);
+        dwd.setDeepConversionsCostDay(0L);
+        dwd.setDeepConversionsCostHour(0L);
+        dwd.setDeepConversionsCostMinute(0L);
+        dwd.setDeepConversionsRateAll(0.0);
+        dwd.setDeepConversionsRateDay(0.0);
+        dwd.setDeepConversionsRateHour(0.0);
+        dwd.setDeepConversionsRateMinute(0.0);
+        dwd.setOrderCountTotal(0L);
+        dwd.setOrderCountDay(0L);
+        dwd.setOrderCountHour(0L);
+        dwd.setOrderCountMinute(0L);
+        dwd.setFirstDayOrderCountTotal(0L);
+        dwd.setFirstDayOrderCountDay(0L);
+        dwd.setFirstDayOrderCountHour(0L);
+        dwd.setFirstDayOrderCountMinute(0L);
+        dwd.setWebOrderCostAll(0L);
+        dwd.setWebOrderCostDay(0L);
+        dwd.setWebOrderCostHour(0L);
+        dwd.setWebOrderCostMinute(0L);
+        dwd.setOrderRateAll(0.0);
+        dwd.setOrderRateDay(0.0);
+        dwd.setOrderRateHour(0.0);
+        dwd.setOrderRateMinute(0.0);
+        dwd.setOrderAmountTotal(0L);
+        dwd.setOrderAmountDay(0L);
+        dwd.setOrderAmountHour(0L);
+        dwd.setOrderAmountMinute(0L);
+        dwd.setFirstDayOrderAmountTotal(0L);
+        dwd.setFirstDayOrderAmountDay(0L);
+        dwd.setFirstDayOrderAmountHour(0L);
+        dwd.setFirstDayOrderAmountMinute(0L);
+        dwd.setOrderUnitPriceAll(0L);
+        dwd.setOrderUnitPriceDay(0L);
+        dwd.setOrderUnitPriceHour(0L);
+        dwd.setOrderUnitPriceMinute(0L);
+        dwd.setOrderRoiAll(0.0);
+        dwd.setOrderRoiDay(0.0);
+        dwd.setOrderRoiHour(0.0);
+        dwd.setOrderRoiMinute(0.0);
+        dwd.setSignInCountTotal(0L);
+        dwd.setSignInCountDay(0L);
+        dwd.setSignInCountHour(0L);
+        dwd.setSignInCountMinute(0L);
+        dwd.setScanFollowCountTotal(0L);
+        dwd.setScanFollowCountDay(0L);
+        dwd.setScanFollowCountHour(0L);
+        dwd.setScanFollowCountMinute(0L);
+        dwd.setWechatAppRegisterUvTotal(0L);
+        dwd.setWechatAppRegisterUvDay(0L);
+        dwd.setWechatAppRegisterUvHour(0L);
+        dwd.setWechatAppRegisterUvMinute(0L);
+        dwd.setWechatMinigameRegisterCostAll(0L);
+        dwd.setWechatMinigameRegisterCostDay(0L);
+        dwd.setWechatMinigameRegisterCostHour(0L);
+        dwd.setWechatMinigameRegisterCostMinute(0L);
+        dwd.setWechatMinigameRegisterRateAll(0.0);
+        dwd.setWechatMinigameRegisterRateDay(0.0);
+        dwd.setWechatMinigameRegisterRateHour(0.0);
+        dwd.setWechatMinigameRegisterRateMinute(0.0);
+        dwd.setWechatMinigameArpuAll(0.0);
+        dwd.setWechatMinigameArpuDay(0.0);
+        dwd.setWechatMinigameArpuHour(0.0);
+        dwd.setWechatMinigameArpuMinute(0.0);
+        dwd.setWechatMinigameRetentionCountTotal(0L);
+        dwd.setWechatMinigameRetentionCountDay(0L);
+        dwd.setWechatMinigameRetentionCountHour(0L);
+        dwd.setWechatMinigameRetentionCountMinute(0L);
+        dwd.setWechatMinigameCheckoutCountTotal(0L);
+        dwd.setWechatMinigameCheckoutCountDay(0L);
+        dwd.setWechatMinigameCheckoutCountHour(0L);
+        dwd.setWechatMinigameCheckoutCountMinute(0L);
+        dwd.setWechatMinigameCheckoutAmountTotal(0L);
+        dwd.setWechatMinigameCheckoutAmountDay(0L);
+        dwd.setWechatMinigameCheckoutAmountHour(0L);
+        dwd.setWechatMinigameCheckoutAmountMinute(0L);
+        dwd.setOfficialAccountFollowCountTotal(0L);
+        dwd.setOfficialAccountFollowCountDay(0L);
+        dwd.setOfficialAccountFollowCountHour(0L);
+        dwd.setOfficialAccountFollowCountMinute(0L);
+        dwd.setOfficialAccountFollowRateAll(0.0);
+        dwd.setOfficialAccountFollowRateDay(0.0);
+        dwd.setOfficialAccountFollowRateHour(0.0);
+        dwd.setOfficialAccountFollowRateMinute(0.0);
+        dwd.setOfficialAccountRegisterUserCountTotal(0L);
+        dwd.setOfficialAccountRegisterUserCountDay(0L);
+        dwd.setOfficialAccountRegisterUserCountHour(0L);
+        dwd.setOfficialAccountRegisterUserCountMinute(0L);
+        dwd.setOfficialAccountRegisterRateAll(0.0);
+        dwd.setOfficialAccountRegisterRateDay(0.0);
+        dwd.setOfficialAccountRegisterRateHour(0.0);
+        dwd.setOfficialAccountRegisterRateMinute(0.0);
+        dwd.setOfficialAccountRegisterCostAll(0L);
+        dwd.setOfficialAccountRegisterCostDay(0L);
+        dwd.setOfficialAccountRegisterCostHour(0L);
+        dwd.setOfficialAccountRegisterCostMinute(0L);
+        dwd.setOfficialAccountRegisterAmountTotal(0L);
+        dwd.setOfficialAccountRegisterAmountDay(0L);
+        dwd.setOfficialAccountRegisterAmountHour(0L);
+        dwd.setOfficialAccountRegisterAmountMinute(0L);
+        dwd.setOfficialAccountRegisterRoiAll(0L);
+        dwd.setOfficialAccountRegisterRoiDay(0L);
+        dwd.setOfficialAccountRegisterRoiHour(0L);
+        dwd.setOfficialAccountRegisterRoiMinute(0L);
+        dwd.setOfficialAccountApplyCountTotal(0L);
+        dwd.setOfficialAccountApplyCountDay(0L);
+        dwd.setOfficialAccountApplyCountHour(0L);
+        dwd.setOfficialAccountApplyCountMinute(0L);
+        dwd.setOfficialAccountApplyUserCountTotal(0L);
+        dwd.setOfficialAccountApplyUserCountDay(0L);
+        dwd.setOfficialAccountApplyUserCountHour(0L);
+        dwd.setOfficialAccountApplyUserCountMinute(0L);
+        dwd.setOfficialAccountApplyRateAll(0.0);
+        dwd.setOfficialAccountApplyRateDay(0.0);
+        dwd.setOfficialAccountApplyRateHour(0.0);
+        dwd.setOfficialAccountApplyRateMinute(0.0);
+        dwd.setOfficialAccountApplyCostAll(0L);
+        dwd.setOfficialAccountApplyCostDay(0L);
+        dwd.setOfficialAccountApplyCostHour(0L);
+        dwd.setOfficialAccountApplyCostMinute(0L);
+        dwd.setOfficialAccountApplyAmountTotal(0L);
+        dwd.setOfficialAccountApplyAmountDay(0L);
+        dwd.setOfficialAccountApplyAmountHour(0L);
+        dwd.setOfficialAccountApplyAmountMinute(0L);
+        dwd.setOfficialAccountApplyRoiAll(0L);
+        dwd.setOfficialAccountApplyRoiDay(0L);
+        dwd.setOfficialAccountApplyRoiHour(0L);
+        dwd.setOfficialAccountApplyRoiMinute(0L);
+        dwd.setOfficialAccountOrderCountTotal(0L);
+        dwd.setOfficialAccountOrderCountDay(0L);
+        dwd.setOfficialAccountOrderCountHour(0L);
+        dwd.setOfficialAccountOrderCountMinute(0L);
+        dwd.setOfficialAccountFirstDayOrderCountTotal(0L);
+        dwd.setOfficialAccountFirstDayOrderCountDay(0L);
+        dwd.setOfficialAccountFirstDayOrderCountHour(0L);
+        dwd.setOfficialAccountFirstDayOrderCountMinute(0L);
+        dwd.setOfficialAccountOrderUserCountTotal(0L);
+        dwd.setOfficialAccountOrderUserCountDay(0L);
+        dwd.setOfficialAccountOrderUserCountHour(0L);
+        dwd.setOfficialAccountOrderUserCountMinute(0L);
+        dwd.setOfficialAccountOrderRateAll(0.0);
+        dwd.setOfficialAccountOrderRateDay(0.0);
+        dwd.setOfficialAccountOrderRateHour(0.0);
+        dwd.setOfficialAccountOrderRateMinute(0.0);
+        dwd.setOfficialAccountOrderCostAll(0L);
+        dwd.setOfficialAccountOrderCostDay(0L);
+        dwd.setOfficialAccountOrderCostHour(0L);
+        dwd.setOfficialAccountOrderCostMinute(0L);
+        dwd.setOfficialAccountOrderAmountTotal(0L);
+        dwd.setOfficialAccountOrderAmountDay(0L);
+        dwd.setOfficialAccountOrderAmountHour(0L);
+        dwd.setOfficialAccountOrderAmountMinute(0L);
+        dwd.setOfficialAccountFirstDayOrderAmountTotal(0L);
+        dwd.setOfficialAccountFirstDayOrderAmountDay(0L);
+        dwd.setOfficialAccountFirstDayOrderAmountHour(0L);
+        dwd.setOfficialAccountFirstDayOrderAmountMinute(0L);
+        dwd.setOfficialAccountOrderRoiAll(0L);
+        dwd.setOfficialAccountOrderRoiDay(0L);
+        dwd.setOfficialAccountOrderRoiHour(0L);
+        dwd.setOfficialAccountOrderRoiMinute(0L);
+        dwd.setOfficialAccountConsultCountTotal(0L);
+        dwd.setOfficialAccountConsultCountDay(0L);
+        dwd.setOfficialAccountConsultCountHour(0L);
+        dwd.setOfficialAccountConsultCountMinute(0L);
+        dwd.setOfficialAccountReaderCountTotal(0L);
+        dwd.setOfficialAccountReaderCountDay(0L);
+        dwd.setOfficialAccountReaderCountHour(0L);
+        dwd.setOfficialAccountReaderCountMinute(0L);
+        dwd.setOfficialAccountCreditApplyUserCountTotal(0L);
+        dwd.setOfficialAccountCreditApplyUserCountDay(0L);
+        dwd.setOfficialAccountCreditApplyUserCountHour(0L);
+        dwd.setOfficialAccountCreditApplyUserCountMinute(0L);
+        dwd.setOfficialAccountCreditUserCountTotal(0L);
+        dwd.setOfficialAccountCreditUserCountDay(0L);
+        dwd.setOfficialAccountCreditUserCountHour(0L);
+        dwd.setOfficialAccountCreditUserCountMinute(0L);
+        dwd.setForwardCountTotal(0L);
+        dwd.setForwardCountDay(0L);
+        dwd.setForwardCountHour(0L);
+        dwd.setForwardCountMinute(0L);
+        dwd.setForwardUserCountTotal(0L);
+        dwd.setForwardUserCountDay(0L);
+        dwd.setForwardUserCountHour(0L);
+        dwd.setForwardUserCountMinute(0L);
+        dwd.setNoInterestCountTotal(0L);
+        dwd.setNoInterestCountDay(0L);
+        dwd.setNoInterestCountHour(0L);
+        dwd.setNoInterestCountMinute(0L);
+        return dwd;
+    }
 }

+ 1498 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/PlanStatOfDayDWD.java

@@ -0,0 +1,1498 @@
+package flink.zanxiangnet.ad.monitoring.pojo.entity;
+
+import com.aliyun.odps.data.Record;
+import com.google.gson.annotations.SerializedName;
+import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeColumn;
+import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeTable;
+import flink.zanxiangnet.ad.monitoring.util.JsonUtil;
+import flink.zanxiangnet.ad.monitoring.util.ObjectUtil;
+import flink.zanxiangnet.ad.monitoring.util.PlanUtil;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Data
+@MaxComputeTable("plan_stat_of_day_dwd")
+public class PlanStatOfDayDWD implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 统计日 yyyy-MM-dd(用于 MaxCompute分区)
+     */
+    @MaxComputeColumn(isPartitioned = true)
+    @SerializedName("stat_day")
+    private String statDay;
+
+    /**
+     * 应用下的账号 id
+     */
+    @SerializedName("account_id")
+    private Long accountId;
+
+    /**
+     * 计划 id
+     */
+    @SerializedName("campaign_id")
+    private Long campaignId;
+
+    /**
+     * 服务商账号 id
+     */
+    @SerializedName("agency_account_id")
+    private Long agencyAccountId;
+
+    /**
+     * 微信账号id
+     */
+    @SerializedName("wechat_account_id")
+    private String wechatAccountId;
+
+    /**
+     * 微信服务商id
+     */
+    @SerializedName("wechat_agency_id")
+    private String wechatAgencyId;
+
+    /**
+     * 广告组与广告的映射关系
+     */
+    @MaxComputeColumn(ignore = true)
+    @SerializedName("ad_group_map")
+    private Map<Long, List<Long>> adGroupMap;
+
+    /**
+     * 广告组与广告的映射关系
+     */
+    @SerializedName("ad_group_map_str")
+    private String adGroupMapStr;
+
+    /**
+     * 广告 id列表
+     */
+    @MaxComputeColumn(ignore = true)
+    @SerializedName("ad_ids")
+    private Set<Long> adIds;
+
+    /**
+     * 广告 id列表
+     */
+    @SerializedName("ad_ids_str")
+    private String adIdsStr;
+
+    /**
+     * 记录创建时间
+     */
+    @SerializedName("create_time")
+    private Date createTime;
+
+    /**
+     * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
+     */
+    @SerializedName("cost_deviation_rate_total")
+    private Double costDeviationRateTotal;
+
+    /**
+     * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
+     */
+    @SerializedName("cost_deviation_rate_day")
+    private Double costDeviationRateDay;
+
+    /**
+     * 消耗
+     */
+    @SerializedName("cost_total")
+    private Long costTotal;
+
+    /**
+     * 消耗
+     */
+    @SerializedName("cost_day")
+    private Long costDay;
+
+    /**
+     * 赔付金额。智能优化成本保障政策下,广告超成本时的赔付金额。
+     */
+    @SerializedName("compensation_amount_total")
+    private Long compensationAmountTotal;
+
+    /**
+     * 赔付金额。智能优化成本保障政策下,广告超成本时的赔付金额。
+     */
+    @SerializedName("compensation_amount_day")
+    private Long compensationAmountDay;
+
+    /**
+     * 曝光次数。用户观看广告的次数。
+     */
+    @SerializedName("view_count_total")
+    private Long viewCountTotal;
+
+    /**
+     * 曝光次数。用户观看广告的次数。
+     */
+    @SerializedName("view_count_day")
+    private Long viewCountDay;
+
+    /**
+     * 千次曝光成本。平均每千次曝光的花费。
+     */
+    @SerializedName("thousand_display_price_all")
+    private Long thousandDisplayPriceAll;
+
+    /**
+     * 千次曝光成本。平均每千次曝光的花费。
+     */
+    @SerializedName("thousand_display_price_day")
+    private Long thousandDisplayPriceDay;
+
+    /**
+     * 曝光人数。观看广告的独立用户数。
+     */
+    @SerializedName("view_user_count_total")
+    private Long viewUserCountTotal;
+
+    /**
+     * 曝光人数。观看广告的独立用户数。
+     */
+    @SerializedName("view_user_count_day")
+    private Long viewUserCountDay;
+
+    /**
+     * 人均曝光次数。每个用户观看广告的平均次数。
+     */
+    @SerializedName("avg_view_per_user_all")
+    private Double avgViewPerUserAll;
+
+    /**
+     * 人均曝光次数。每个用户观看广告的平均次数。
+     */
+    @SerializedName("avg_view_per_user_day")
+    private Double avgViewPerUserDay;
+
+    /**
+     * 点击次数。用户在广告外层进行点击操作的次数。包括点击图片/视频,及朋友圈广告“文字链、头像、昵称、门店、选择按钮”等所有广告外层区域的点击。
+     */
+    @SerializedName("valid_click_count_total")
+    private Long validClickCountTotal;
+
+    /**
+     * 点击次数。用户在广告外层进行点击操作的次数。包括点击图片/视频,及朋友圈广告“文字链、头像、昵称、门店、选择按钮”等所有广告外层区域的点击。
+     */
+    @SerializedName("valid_click_count_day")
+    private Long validClickCountDay;
+
+    /**
+     * 点击人数。在广告外层进行点击操作的独立用户数。
+     */
+    @SerializedName("click_user_count_total")
+    private Long clickUserCountTotal;
+
+    /**
+     * 点击人数。在广告外层进行点击操作的独立用户数。
+     */
+    @SerializedName("click_user_count_day")
+    private Long clickUserCountDay;
+
+    /**
+     * 点击率。看到广告后执行点击操作的百分比。计算逻辑:广告点击次数/广告曝光次数。
+     */
+    @SerializedName("ctr_all")
+    private Double ctrAll;
+
+    /**
+     * 点击率。看到广告后执行点击操作的百分比。计算逻辑:广告点击次数/广告曝光次数。
+     */
+    @SerializedName("ctr_day")
+    private Double ctrDay;
+
+    /**
+     * 点击均价。一次广告点击的平均花费。计算逻辑:广告花费/广告点击次数。
+     */
+    @SerializedName("cpc_all")
+    private Long cpcAll;
+
+    /**
+     * 点击均价。一次广告点击的平均花费。计算逻辑:广告花费/广告点击次数。
+     */
+    @SerializedName("cpc_day")
+    private Long cpcDay;
+
+    /**
+     * 可转化点击次数。朋友圈:可转化点击是指可能产生转化的外层点击次数。对于“公众号推广”的广告,包括外层的公众号头像、公众号昵称、详情页查看、原生推广页查看; 对于其他类型的广告,包括外层的详情页查看和原生推广页查看。公众号:可转化点击是指可能产生转化的点击次数。
+     */
+    @SerializedName("valuable_click_count_total")
+    private Long valuableClickCountTotal;
+
+    /**
+     * 可转化点击次数。朋友圈:可转化点击是指可能产生转化的外层点击次数。对于“公众号推广”的广告,包括外层的公众号头像、公众号昵称、详情页查看、原生推广页查看; 对于其他类型的广告,包括外层的详情页查看和原生推广页查看。公众号:可转化点击是指可能产生转化的点击次数。
+     */
+    @SerializedName("valuable_click_count_day")
+    private Long valuableClickCountDay;
+
+    /**
+     * 可转化点击率。用户看到广告后执行可转化点击操作的百分比。计算逻辑:广告可转化点击次数/广告曝光次数。
+     */
+    @SerializedName("valuable_click_rate_all")
+    private Double valuableClickRateAll;
+
+    /**
+     * 可转化点击率。用户看到广告后执行可转化点击操作的百分比。计算逻辑:广告可转化点击次数/广告曝光次数。
+     */
+    @SerializedName("valuable_click_rate_day")
+    private Double valuableClickRateDay;
+
+    /**
+     * 可转化点击成本。一次可转化点击的平均花费。计算逻辑:广告花费/可转化点击次数。
+     */
+    @SerializedName("valuable_click_cost_all")
+    private Long valuableClickCostAll;
+
+    /**
+     * 可转化点击成本。一次可转化点击的平均花费。计算逻辑:广告花费/可转化点击次数。
+     */
+    @SerializedName("valuable_click_cost_day")
+    private Long valuableClickCostDay;
+
+    /**
+     * 转化目标量。「转化目标」的具体数量,代表该广告的转化效果量级。
+     */
+    @SerializedName("conversions_count_total")
+    private Long conversionsCountTotal;
+
+    /**
+     * 转化目标量。「转化目标」的具体数量,代表该广告的转化效果量级。
+     */
+    @SerializedName("conversions_count_day")
+    private Long conversionsCountDay;
+
+    /**
+     * 转化目标成本。广告产生一次转化目标的平均费用。计算逻辑:广告花费/转化目标量。
+     */
+    @SerializedName("conversions_cost_all")
+    private Long conversionsCostAll;
+
+    /**
+     * 转化目标成本。广告产生一次转化目标的平均费用。计算逻辑:广告花费/转化目标量。
+     */
+    @SerializedName("conversions_cost_day")
+    private Long conversionsCostDay;
+
+    /**
+     * 目标转化率。朋友圈:转化目标量/可转化点击次数。公众号:转化目标量/点击次数。
+     */
+    @SerializedName("conversions_rate_all")
+    private Double conversionsRateAll;
+
+    /**
+     * 目标转化率。朋友圈:转化目标量/可转化点击次数。公众号:转化目标量/点击次数。
+     */
+    @SerializedName("conversions_rate_day")
+    private Double conversionsRateDay;
+
+    /**
+     * 深度转化目标量-灰度中。根据您选择的深度智能优化目标,该广告对应的具体数量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_count_total")
+    private Long deepConversionsCountTotal;
+
+    /**
+     * 深度转化目标量-灰度中。根据您选择的深度智能优化目标,该广告对应的具体数量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_count_day")
+    private Long deepConversionsCountDay;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost_all")
+    private Long deepConversionsCostAll;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost_day")
+    private Long deepConversionsCostDay;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate_all")
+    private Double deepConversionsRateAll;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate_day")
+    private Double deepConversionsRateDay;
+
+    /**
+     * 关键页面访问人数。点击广告原生落地页的APP跳转按钮,并到达APP内关键页面的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("key_page_uv_total")
+    private Long keyPageUvTotal;
+
+    /**
+     * 关键页面访问人数。点击广告原生落地页的APP跳转按钮,并到达APP内关键页面的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("key_page_uv_day")
+    private Long keyPageUvDay;
+
+    /**
+     * 下单量。用户通过该广告进行商品成交(如下单提交、在线支付)的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_count_total")
+    private Long orderCountTotal;
+
+    /**
+     * 下单量。用户通过该广告进行商品成交(如下单提交、在线支付)的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_count_day")
+    private Long orderCountDay;
+
+    /**
+     * 首日新增下单量。广告推广获取的用户,点击广告当日,带来的下单次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_count_total")
+    private Long firstDayOrderCountTotal;
+
+    /**
+     * 首日新增下单量。广告推广获取的用户,点击广告当日,带来的下单次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_count_day")
+    private Long firstDayOrderCountDay;
+
+    /**
+     * 下单成本(次数)。产生一次下单的成本。
+     */
+    @SerializedName("web_order_cost_all")
+    private Long webOrderCostAll;
+
+    /**
+     * 下单成本(次数)。产生一次下单的成本。
+     */
+    @SerializedName("web_order_cost_day")
+    private Long webOrderCostDay;
+
+    /**
+     * 下单率。一次点击到下单的转化率。
+     */
+    @SerializedName("order_rate_all")
+    private Double orderRateAll;
+
+    /**
+     * 下单率。一次点击到下单的转化率。
+     */
+    @SerializedName("order_rate_day")
+    private Double orderRateDay;
+
+    /**
+     * 下单金额。广告带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_amount_total")
+    private Long orderAmountTotal;
+
+    /**
+     * 下单金额。广告带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_amount_day")
+    private Long orderAmountDay;
+
+    /**
+     * 首日新增下单金额。广告推广获取的用户,点击广告当日,带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_amount_total")
+    private Long firstDayOrderAmountTotal;
+
+    /**
+     * 首日新增下单金额。广告推广获取的用户,点击广告当日,带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_amount_day")
+    private Long firstDayOrderAmountDay;
+
+    /**
+     * 下单客单价。下单金额/下单量。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_unit_price_all")
+    private Long orderUnitPriceAll;
+
+    /**
+     * 下单客单价。下单金额/下单量。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_unit_price_day")
+    private Long orderUnitPriceDay;
+
+    /**
+     * 下单ROI。下单金额/广告花费。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_roi_all")
+    private Double orderRoiAll;
+
+    /**
+     * 下单ROI。下单金额/广告花费。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_roi_day")
+    private Double orderRoiDay;
+
+    /**
+     * 签收次数。签收从广告主处购买的商品的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("sign_in_count_total")
+    private Long signInCountTotal;
+
+    /**
+     * 签收次数。签收从广告主处购买的商品的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("sign_in_count_day")
+    private Long signInCountDay;
+
+    /**
+     * 加收藏次数。用户将广告主商品加入收藏的次数,接入转化跟踪后可统计。
+     */
+    @SerializedName("add_wishlist_count_total")
+    private Long addWishlistCountTotal;
+
+    /**
+     * 加收藏次数。用户将广告主商品加入收藏的次数,接入转化跟踪后可统计。
+     */
+    @SerializedName("add_wishlist_count_day")
+    private Long addWishlistCountDay;
+
+    /**
+     * 商品详情页浏览人数。浏览广告主商品详情页的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("view_commodity_page_uv_total")
+    private Long viewCommodityPageUvTotal;
+
+    /**
+     * 商品详情页浏览人数。浏览广告主商品详情页的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("view_commodity_page_uv_day")
+    private Long viewCommodityPageUvDay;
+
+    /**
+     * 销售线索次数。广告带来的用户销售线索数量。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("page_reservation_count_total")
+    private Long pageReservationCountTotal;
+
+    /**
+     * 销售线索次数。广告带来的用户销售线索数量。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("page_reservation_count_day")
+    private Long pageReservationCountDay;
+
+    /**
+     * 首次付费人数。广告带来的有付费行为的销售线索数量按用户去重,同一个用户多次提交仅计算一次(原付费销售线索人数)。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("leads_purchase_uv_total")
+    private Long leadsPurchaseUvTotal;
+
+    /**
+     * 首次付费人数。广告带来的有付费行为的销售线索数量按用户去重,同一个用户多次提交仅计算一次(原付费销售线索人数)。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("leads_purchase_uv_day")
+    private Long leadsPurchaseUvDay;
+
+    /**
+     * 首次付费成本(人数)。产生一个首次付费用户的成本(原付费销售线索成本)。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("leads_purchase_cost_all")
+    private Long leadsPurchaseCostAll;
+
+    /**
+     * 首次付费成本(人数)。产生一个首次付费用户的成本(原付费销售线索成本)。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("leads_purchase_cost_day")
+    private Long leadsPurchaseCostDay;
+
+    /**
+     * 首次付费转化率(人数)。一次点击到产生一个首次付费用户的转化率(原付费销售线索转化率)。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("leads_purchase_rate_all")
+    private Double leadsPurchaseRateAll;
+
+    /**
+     * 首次付费转化率(人数)。一次点击到产生一个首次付费用户的转化率(原付费销售线索转化率)。H5推广需接入转化跟踪后可统计。
+     */
+    @SerializedName("leads_purchase_rate_day")
+    private Double leadsPurchaseRateDay;
+
+    /**
+     * 加企业微信客服人数。添加企业微信好友成功的独立用户数。
+     */
+    @SerializedName("scan_follow_count_total")
+    private Long scanFollowCountTotal;
+
+    /**
+     * 加企业微信客服人数。添加企业微信好友成功的独立用户数。
+     */
+    @SerializedName("scan_follow_count_day")
+    private Long scanFollowCountDay;
+
+    /**
+     * 小游戏注册人数。通过广告首次登录小游戏的独立用户数。
+     */
+    @SerializedName("wechat_app_register_uv_total")
+    private Long wechatAppRegisterUvTotal;
+
+    /**
+     * 小游戏注册人数。通过广告首次登录小游戏的独立用户数。
+     */
+    @SerializedName("wechat_app_register_uv_day")
+    private Long wechatAppRegisterUvDay;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @SerializedName("wechat_minigame_register_cost_all")
+    private Long wechatMinigameRegisterCostAll;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @SerializedName("wechat_minigame_register_cost_day")
+    private Long wechatMinigameRegisterCostDay;
+
+    /**
+     * 小游戏注册率。一次点击到小游戏注册的转化率。
+     */
+    @SerializedName("wechat_minigame_register_rate_all")
+    private Double wechatMinigameRegisterRateAll;
+
+    /**
+     * 小游戏注册率。一次点击到小游戏注册的转化率。
+     */
+    @SerializedName("wechat_minigame_register_rate_day")
+    private Double wechatMinigameRegisterRateDay;
+
+    /**
+     * 首日新增广告ARPU。广告带来的注册用户,在注册当日,产生的平均广告变现收入。注:该指标天更新,可以查看昨天及以前的数据。
+     */
+    @SerializedName("wechat_minigame_arpu_all")
+    private Double wechatMinigameArpuAll;
+
+    /**
+     * 首日新增广告ARPU。广告带来的注册用户,在注册当日,产生的平均广告变现收入。注:该指标天更新,可以查看昨天及以前的数据。
+     */
+    @SerializedName("wechat_minigame_arpu_day")
+    private Double wechatMinigameArpuDay;
+
+    /**
+     * 小游戏次留人数。通过广告首次登录小游戏,并在第二天再次登录的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_retention_count_total")
+    private Long wechatMinigameRetentionCountTotal;
+
+    /**
+     * 小游戏次留人数。通过广告首次登录小游戏,并在第二天再次登录的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_retention_count_day")
+    private Long wechatMinigameRetentionCountDay;
+
+    /**
+     * 小游戏付费次数。通过广告进入小游戏并完成付费的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_count_total")
+    private Long wechatMinigameCheckoutCountTotal;
+
+    /**
+     * 小游戏付费次数。通过广告进入小游戏并完成付费的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_count_day")
+    private Long wechatMinigameCheckoutCountDay;
+
+    /**
+     * 小游戏付费金额。通过广告进入小游戏并完成付费的金额。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_amount_total")
+    private Long wechatMinigameCheckoutAmountTotal;
+
+    /**
+     * 小游戏付费金额。通过广告进入小游戏并完成付费的金额。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_amount_day")
+    private Long wechatMinigameCheckoutAmountDay;
+
+    /**
+     * 公众号关注次数。用户通过广告关注公众号成功的次数。
+     */
+    @SerializedName("official_account_follow_count_total")
+    private Long officialAccountFollowCountTotal;
+
+    /**
+     * 公众号关注次数。用户通过广告关注公众号成功的次数。
+     */
+    @SerializedName("official_account_follow_count_day")
+    private Long officialAccountFollowCountDay;
+
+    /**
+     * 公众号关注成本(次数)。产生一次公众号关注的成本。
+     */
+    @SerializedName("official_account_follow_cost_all")
+    private Long officialAccountFollowCostAll;
+
+    /**
+     * 公众号关注成本(次数)。产生一次公众号关注的成本。
+     */
+    @SerializedName("official_account_follow_cost_day")
+    private Long officialAccountFollowCostDay;
+
+    /**
+     * 公众号关注率。一次点击到公众号关注的转化率。
+     */
+    @SerializedName("official_account_follow_rate_all")
+    private Double officialAccountFollowRateAll;
+
+    /**
+     * 公众号关注率。一次点击到公众号关注的转化率。
+     */
+    @SerializedName("official_account_follow_rate_day")
+    private Double officialAccountFollowRateDay;
+
+    /**
+     * 公众号内注册人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的注册行为的人数(UV)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_user_count_total")
+    private Long officialAccountRegisterUserCountTotal;
+
+    /**
+     * 公众号内注册人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的注册行为的人数(UV)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_user_count_day")
+    private Long officialAccountRegisterUserCountDay;
+
+    /**
+     * 公众号内注册比例。公众号内注册独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_rate_all")
+    private Double officialAccountRegisterRateAll;
+
+    /**
+     * 公众号内注册比例。公众号内注册独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_rate_day")
+    private Double officialAccountRegisterRateDay;
+
+    /**
+     * 公众号内注册成本。广告花费/广告产生的注册行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_cost_all")
+    private Long officialAccountRegisterCostAll;
+
+    /**
+     * 公众号内注册成本。广告花费/广告产生的注册行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_cost_day")
+    private Long officialAccountRegisterCostDay;
+
+    /**
+     * 公众号内注册订单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的订单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_amount_total")
+    private Long officialAccountRegisterAmountTotal;
+
+    /**
+     * 公众号内注册订单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的订单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_amount_day")
+    private Long officialAccountRegisterAmountDay;
+
+    /**
+     * 公众号内注册ROI。注册产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_roi_all")
+    private Long officialAccountRegisterRoiAll;
+
+    /**
+     * 公众号内注册ROI。注册产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_roi_day")
+    private Long officialAccountRegisterRoiDay;
+
+    /**
+     * 公众号内填单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_count_total")
+    private Long officialAccountApplyCountTotal;
+
+    /**
+     * 公众号内填单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_count_day")
+    private Long officialAccountApplyCountDay;
+
+    /**
+     * 公众号内填单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_user_count_total")
+    private Long officialAccountApplyUserCountTotal;
+
+    /**
+     * 公众号内填单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_user_count_day")
+    private Long officialAccountApplyUserCountDay;
+
+    /**
+     * 公众号内填单比例。公众号内填单的独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_rate_all")
+    private Double officialAccountApplyRateAll;
+
+    /**
+     * 公众号内填单比例。公众号内填单的独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_rate_day")
+    private Double officialAccountApplyRateDay;
+
+    /**
+     * 公众号内填单成本。广告花费/广告产生的填单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_cost_all")
+    private Long officialAccountApplyCostAll;
+
+    /**
+     * 公众号内填单成本。广告花费/广告产生的填单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_cost_day")
+    private Long officialAccountApplyCostDay;
+
+    /**
+     * 公众号内填单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_amount_total")
+    private Long officialAccountApplyAmountTotal;
+
+    /**
+     * 公众号内填单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_amount_day")
+    private Long officialAccountApplyAmountDay;
+
+    /**
+     * 公众号内填单ROI。填单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_roi_all")
+    private Long officialAccountApplyRoiAll;
+
+    /**
+     * 公众号内填单ROI。填单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_roi_day")
+    private Long officialAccountApplyRoiDay;
+
+    /**
+     * 公众号内下单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_count_total")
+    private Long officialAccountOrderCountTotal;
+
+    /**
+     * 公众号内下单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_count_day")
+    private Long officialAccountOrderCountDay;
+
+    /**
+     * 首日公众号内下单次数。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为数量。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_count_total")
+    private Long officialAccountFirstDayOrderCountTotal;
+
+    /**
+     * 首日公众号内下单次数。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为数量。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_count_day")
+    private Long officialAccountFirstDayOrderCountDay;
+
+    /**
+     * 公众号内下单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_user_count_total")
+    private Long officialAccountOrderUserCountTotal;
+
+    /**
+     * 公众号内下单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_user_count_day")
+    private Long officialAccountOrderUserCountDay;
+
+    /**
+     * 公众号内下单比例。公众号内下单独立用户数(UV)/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_rate_all")
+    private Double officialAccountOrderRateAll;
+
+    /**
+     * 公众号内下单比例。公众号内下单独立用户数(UV)/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_rate_day")
+    private Double officialAccountOrderRateDay;
+
+    /**
+     * 公众号内下单成本。广告花费/广告产生的下单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_cost_all")
+    private Long officialAccountOrderCostAll;
+
+    /**
+     * 公众号内下单成本。广告花费/广告产生的下单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_cost_day")
+    private Long officialAccountOrderCostDay;
+
+    /**
+     * 公众号内下单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_amount_total")
+    private Long officialAccountOrderAmountTotal;
+
+    /**
+     * 公众号内下单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_amount_day")
+    private Long officialAccountOrderAmountDay;
+
+    /**
+     * 首日公众号内下单金额。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_amount_total")
+    private Long officialAccountFirstDayOrderAmountTotal;
+
+    /**
+     * 首日公众号内下单金额。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_amount_day")
+    private Long officialAccountFirstDayOrderAmountDay;
+
+    /**
+     * 公众号内下单ROI。下单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_roi_all")
+    private Long officialAccountOrderRoiAll;
+
+    /**
+     * 公众号内下单ROI。下单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_roi_day")
+    private Long officialAccountOrderRoiDay;
+
+    /**
+     * 公众号内发消息人数。用户关注公众号后,在公众号对话框内发送消息的独立用户数。
+     */
+    @SerializedName("official_account_consult_count_total")
+    private Long officialAccountConsultCountTotal;
+
+    /**
+     * 公众号内发消息人数。用户关注公众号后,在公众号对话框内发送消息的独立用户数。
+     */
+    @SerializedName("official_account_consult_count_day")
+    private Long officialAccountConsultCountDay;
+
+    /**
+     * 阅读粉丝量。近3日新增的粉丝中产生阅读行为的用户数。
+     */
+    @SerializedName("official_account_reader_count_total")
+    private Long officialAccountReaderCountTotal;
+
+    /**
+     * 阅读粉丝量。近3日新增的粉丝中产生阅读行为的用户数。
+     */
+    @SerializedName("official_account_reader_count_day")
+    private Long officialAccountReaderCountDay;
+
+    /**
+     * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_apply_user_count_total")
+    private Long officialAccountCreditApplyUserCountTotal;
+
+    /**
+     * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_apply_user_count_day")
+    private Long officialAccountCreditApplyUserCountDay;
+
+    /**
+     * 公众号内授信人数。在公众号内完整提交贷款申请资料,并通过放款方的资质审核的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_user_count_total")
+    private Long officialAccountCreditUserCountTotal;
+
+    /**
+     * 公众号内授信人数。在公众号内完整提交贷款申请资料,并通过放款方的资质审核的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_user_count_day")
+    private Long officialAccountCreditUserCountDay;
+
+    /**
+     * 广告分享次数。用户将广告落地页分享给好友和朋友圈的次数。
+     */
+    @SerializedName("forward_count_total")
+    private Long forwardCountTotal;
+
+    /**
+     * 广告分享次数。用户将广告落地页分享给好友和朋友圈的次数。
+     */
+    @SerializedName("forward_count_day")
+    private Long forwardCountDay;
+
+    /**
+     * 广告分享人数。将广告落地页分享给好友和朋友圈的独立用户数。
+     */
+    @SerializedName("forward_user_count_total")
+    private Long forwardUserCountTotal;
+
+    /**
+     * 广告分享人数。将广告落地页分享给好友和朋友圈的独立用户数。
+     */
+    @SerializedName("forward_user_count_day")
+    private Long forwardUserCountDay;
+
+    /**
+     * 不感兴趣点击次数。用户点击“不感兴趣”的次数。
+     */
+    @SerializedName("no_interest_count_total")
+    private Long noInterestCountTotal;
+
+    /**
+     * 不感兴趣点击次数。用户点击“不感兴趣”的次数。
+     */
+    @SerializedName("no_interest_count_day")
+    private Long noInterestCountDay;
+
+    /**
+     * 聚合
+     *
+     * @param value1     之前聚合的值(可能为 null)
+     * @param value2     新值
+     * @param createTime 聚合时间
+     * @return
+     */
+    public static PlanStatOfDayDWD reduce(PlanStatOfDayDWD value1, AdDataOfDayODS value2, long createTime) {
+        PlanStatOfDayDWD result = new PlanStatOfDayDWD();
+        BeanUtils.copyProperties(value2, result);
+        result.setCreateTime(new Date(createTime));
+        if (value1 == null) {
+            Map<Long, List<Long>> adGroupMap = new HashMap<>();
+            List<Long> adIdsTemp = new ArrayList<>(3);
+            adIdsTemp.add(value2.getAdId());
+            adGroupMap.put(value2.getAdgroupId(), adIdsTemp);
+            result.setAdGroupMap(adGroupMap);
+            result.setAdGroupMapStr(PlanUtil.adGroupMapStr(adGroupMap));
+
+            Set<Long> adIds = new HashSet<>(3);
+            adIds.add(value2.getAdId());
+            result.setAdIds(adIds);
+            result.setAdIdsStr(PlanUtil.adIdsStr(value2.getAdId()));
+
+            result.setCostDeviationRateTotal(value2.getCostDeviationRate());
+            result.setCostDeviationRateDay(value2.getCostDeviationRate());
+            result.setCostTotal(value2.getCost());
+            result.setCostDay(value2.getCost());
+            result.setCompensationAmountTotal(value2.getCompensationAmount());
+            result.setCompensationAmountDay(value2.getCompensationAmount());
+            result.setViewCountTotal(value2.getViewCount());
+            result.setViewCountDay(value2.getViewCount());
+            result.setThousandDisplayPriceAll(value2.getThousandDisplayPrice());
+            result.setThousandDisplayPriceDay(value2.getThousandDisplayPrice());
+            result.setViewUserCountTotal(value2.getViewUserCount());
+            result.setViewUserCountDay(value2.getViewUserCount());
+            result.setAvgViewPerUserAll(value2.getAvgViewPerUser());
+            result.setAvgViewPerUserDay(value2.getAvgViewPerUser());
+            result.setValidClickCountTotal(value2.getValidClickCount());
+            result.setValidClickCountDay(value2.getValidClickCount());
+            result.setClickUserCountTotal(value2.getClickUserCount());
+            result.setClickUserCountDay(value2.getClickUserCount());
+            result.setCtrAll(value2.getCtr());
+            result.setCtrDay(value2.getCtr());
+            result.setCpcAll(value2.getCpc());
+            result.setCpcDay(value2.getCpc());
+            result.setValuableClickCountTotal(value2.getValuableClickCount());
+            result.setValuableClickCountDay(value2.getValuableClickCount());
+            result.setValuableClickRateAll(value2.getValuableClickRate());
+            result.setValuableClickRateDay(value2.getValuableClickRate());
+            result.setValuableClickCostAll(value2.getValuableClickCost());
+            result.setValuableClickCostDay(value2.getValuableClickCost());
+            result.setConversionsCountTotal(value2.getConversionsCount());
+            result.setConversionsCountDay(value2.getConversionsCount());
+            result.setConversionsCostAll(value2.getConversionsCost());
+            result.setConversionsCostDay(value2.getConversionsCost());
+            result.setConversionsRateAll(value2.getConversionsRate());
+            result.setConversionsRateDay(value2.getConversionsRate());
+            result.setDeepConversionsCountTotal(value2.getDeepConversionsCount());
+            result.setDeepConversionsCountDay(value2.getDeepConversionsCount());
+            result.setDeepConversionsCostAll(value2.getDeepConversionsCost());
+            result.setDeepConversionsCostDay(value2.getDeepConversionsCost());
+            result.setDeepConversionsRateAll(value2.getDeepConversionsRate());
+            result.setDeepConversionsRateDay(value2.getDeepConversionsRate());
+            result.setKeyPageUvTotal(value2.getKeyPageUv());
+            result.setKeyPageUvDay(value2.getKeyPageUv());
+            result.setOrderCountTotal(value2.getOrderCount());
+            result.setOrderCountDay(value2.getOrderCount());
+            result.setFirstDayOrderCountTotal(value2.getFirstDayOrderCount());
+            result.setFirstDayOrderCountDay(value2.getFirstDayOrderCount());
+            result.setWebOrderCostAll(value2.getWebOrderCost());
+            result.setWebOrderCostDay(value2.getWebOrderCost());
+            result.setOrderRateAll(value2.getOrderRate());
+            result.setOrderRateDay(value2.getOrderRate());
+            result.setOrderAmountTotal(value2.getOrderAmount());
+            result.setOrderAmountDay(value2.getOrderAmount());
+            result.setFirstDayOrderAmountTotal(value2.getFirstDayOrderAmount());
+            result.setFirstDayOrderAmountDay(value2.getFirstDayOrderAmount());
+            result.setOrderUnitPriceAll(value2.getOrderUnitPrice());
+            result.setOrderUnitPriceDay(value2.getOrderUnitPrice());
+            result.setOrderRoiAll(value2.getOrderRoi());
+            result.setOrderRoiDay(value2.getOrderRoi());
+            result.setSignInCountTotal(value2.getSignInCount());
+            result.setSignInCountDay(value2.getSignInCount());
+            result.setAddWishlistCountTotal(value2.getAddWishlistCount());
+            result.setAddWishlistCountDay(value2.getAddWishlistCount());
+            result.setViewCommodityPageUvTotal(value2.getViewCommodityPageUv());
+            result.setViewCommodityPageUvDay(value2.getViewCommodityPageUv());
+            result.setPageReservationCountTotal(value2.getPageReservationCount());
+            result.setPageReservationCountDay(value2.getPageReservationCount());
+            result.setLeadsPurchaseUvTotal(value2.getLeadsPurchaseUv());
+            result.setLeadsPurchaseUvDay(value2.getLeadsPurchaseUv());
+            result.setLeadsPurchaseCostAll(value2.getLeadsPurchaseCost());
+            result.setLeadsPurchaseCostDay(value2.getLeadsPurchaseCost());
+            result.setLeadsPurchaseRateAll(value2.getLeadsPurchaseRate());
+            result.setLeadsPurchaseRateDay(value2.getLeadsPurchaseRate());
+            result.setScanFollowCountTotal(value2.getScanFollowCount());
+            result.setScanFollowCountDay(value2.getScanFollowCount());
+            result.setWechatAppRegisterUvTotal(value2.getWechatAppRegisterUv());
+            result.setWechatAppRegisterUvDay(value2.getWechatAppRegisterUv());
+            result.setWechatMinigameRegisterCostAll(value2.getWechatMinigameRegisterCost());
+            result.setWechatMinigameRegisterCostDay(value2.getWechatMinigameRegisterCost());
+            result.setWechatMinigameRegisterRateAll(value2.getWechatMinigameRegisterRate());
+            result.setWechatMinigameRegisterRateDay(value2.getWechatMinigameRegisterRate());
+            result.setWechatMinigameArpuAll(value2.getWechatMinigameArpu());
+            result.setWechatMinigameArpuDay(value2.getWechatMinigameArpu());
+            result.setWechatMinigameRetentionCountTotal(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameRetentionCountDay(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameCheckoutCountTotal(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutCountDay(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutAmountTotal(value2.getWechatMinigameCheckoutAmount());
+            result.setWechatMinigameCheckoutAmountDay(value2.getWechatMinigameCheckoutAmount());
+            result.setOfficialAccountFollowCountTotal(value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCountDay(value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCostAll(value2.getOfficialAccountFollowCost());
+            result.setOfficialAccountFollowCostDay(value2.getOfficialAccountFollowCost());
+            result.setOfficialAccountFollowRateAll(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountFollowRateDay(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountRegisterUserCountTotal(value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterUserCountDay(value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterRateAll(value2.getOfficialAccountRegisterRate());
+            result.setOfficialAccountRegisterRateDay(value2.getOfficialAccountRegisterRate());
+            result.setOfficialAccountRegisterCostAll(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterCostDay(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterAmountTotal(value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterAmountDay(value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterRoiAll(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountRegisterRoiDay(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountApplyCountTotal(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyCountDay(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyUserCountTotal(value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyUserCountDay(value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyRateAll(value2.getOfficialAccountApplyRate());
+            result.setOfficialAccountApplyRateDay(value2.getOfficialAccountApplyRate());
+            result.setOfficialAccountApplyCostAll(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyCostDay(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyAmountTotal(value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyAmountDay(value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyRoiAll(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountApplyRoiDay(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountOrderCountTotal(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountOrderCountDay(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountFirstDayOrderCountTotal(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountFirstDayOrderCountDay(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountOrderUserCountTotal(value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderUserCountDay(value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderRateAll(value2.getOfficialAccountOrderRate());
+            result.setOfficialAccountOrderRateDay(value2.getOfficialAccountOrderRate());
+            result.setOfficialAccountOrderCostAll(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderCostDay(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderAmountTotal(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountOrderAmountDay(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountTotal(value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountDay(value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountOrderRoiAll(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountOrderRoiDay(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountConsultCountTotal(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountConsultCountDay(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountReaderCountTotal(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountReaderCountDay(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountCreditApplyUserCountTotal(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditApplyUserCountDay(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditUserCountTotal(value2.getOfficialAccountCreditUserCount());
+            result.setOfficialAccountCreditUserCountDay(value2.getOfficialAccountCreditUserCount());
+            result.setForwardCountTotal(value2.getForwardCount());
+            result.setForwardCountDay(value2.getForwardCount());
+            result.setForwardUserCountTotal(value2.getForwardUserCount());
+            result.setForwardUserCountDay(value2.getForwardUserCount());
+            result.setNoInterestCountTotal(value2.getNoInterestCount());
+            result.setNoInterestCountDay(value2.getNoInterestCount());
+        } else {
+            value1.getAdGroupMap().computeIfAbsent(value2.getAdgroupId(), key -> new ArrayList<>(3)).add(value2.getAdId());
+            value1.setAdGroupMapStr(PlanUtil.adGroupMapStr(value1.getAdGroupMap()));
+            value1.getAdIds().add(value2.getAdId());
+            value1.setAdIdsStr(PlanUtil.adIdsStr(value1.getAdIds()));
+
+            result.setCostDeviationRateTotal(value1.getCostDeviationRateTotal() + value2.getCostDeviationRate());
+            result.setCostDeviationRateDay(value2.getCostDeviationRate());
+            result.setCostTotal(value1.getCostTotal() + value2.getCost());
+            result.setCostDay(value2.getCost());
+            result.setCompensationAmountTotal(value1.getCompensationAmountTotal() + value2.getCompensationAmount());
+            result.setCompensationAmountDay(value2.getCompensationAmount());
+            result.setViewCountTotal(value1.getViewCountTotal() + value2.getViewCount());
+            result.setViewCountDay(value2.getViewCount());
+            // 总消耗 / 总曝光
+            result.setThousandDisplayPriceAll(result.getViewCountTotal() == 0 ? 0 : (result.getCostTotal() / result.getViewCountTotal() * 1000));
+            result.setThousandDisplayPriceDay(value2.getThousandDisplayPrice());
+
+            // 应该不准,因为跨天的用户无法去重
+            result.setViewUserCountTotal(value1.getViewUserCountTotal() + value2.getViewUserCount());
+            result.setViewUserCountDay(value2.getViewUserCount());
+            // 曝光次数 / 曝光人数(不准)
+            result.setAvgViewPerUserAll(result.getViewUserCountTotal() == 0 ? 0.0 : result.getViewCountTotal() / result.getViewUserCountTotal());
+            result.setAvgViewPerUserDay(value2.getAvgViewPerUser());
+            result.setValidClickCountTotal(value1.getValidClickCountTotal() + value2.getValidClickCount());
+            result.setValidClickCountDay(value2.getValidClickCount());
+
+            // 应该不准,因为跨天的用户无法去重
+            result.setClickUserCountTotal(value1.getClickUserCountTotal() + value2.getClickUserCount());
+            result.setClickUserCountDay(value2.getClickUserCount());
+            // 广告点击次数 / 广告曝光次数
+            result.setCtrAll(result.getViewCountTotal() == 0 ? 0.0 : result.getValidClickCountTotal() / result.getViewCountTotal());
+            result.setCtrDay(value2.getCtr());
+            // 广告花费/广告点击次数
+            result.setCpcAll(result.getValidClickCountTotal() == 0 ? 0 : result.getCostTotal() / result.getValidClickCountTotal());
+            result.setCpcDay(value2.getCpc());
+            result.setValuableClickCountTotal(value1.getValuableClickCountTotal() + value2.getValuableClickCount());
+            result.setValuableClickCountDay(value2.getValuableClickCount());
+            // 广告可转化点击次数/广告曝光次数
+            result.setValuableClickRateAll(result.getViewCountTotal() == 0 ? 0.0 : result.getValuableClickCountTotal() / result.getViewCountTotal());
+            result.setValuableClickRateDay(value2.getValuableClickRate());
+            // 广告花费/可转化点击次数
+            result.setValuableClickCostAll(result.getValuableClickCountTotal() == 0 ? 0 : result.getCostTotal() / result.getValuableClickCountTotal());
+            result.setValuableClickCostDay(value2.getValuableClickCost());
+            result.setConversionsCountTotal(value1.getConversionsCountTotal() + value2.getConversionsCount());
+            result.setConversionsCountDay(value2.getConversionsCount());
+            // 广告花费/转化目标量
+            result.setConversionsCostAll(result.getConversionsCountTotal() == 0 ? 0 : result.getCostTotal() / result.getConversionsCountTotal());
+            result.setConversionsCostDay(value2.getConversionsCost());
+            // 公众号:转化目标量/点击次数。
+            result.setConversionsRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getConversionsCountTotal() / result.getValidClickCountTotal());
+            result.setConversionsRateDay(value2.getConversionsRate());
+            result.setDeepConversionsCountTotal(value1.getDeepConversionsCountTotal() + value2.getDeepConversionsCount());
+            result.setDeepConversionsCountDay(value2.getDeepConversionsCount());
+            // 广告花费/深度转化目标量
+            result.setDeepConversionsCostAll(result.getDeepConversionsCountTotal() == 0 ? 0 : result.getCostTotal() / result.getDeepConversionsCountTotal());
+            result.setDeepConversionsCostDay(value2.getDeepConversionsCost());
+            // 深度转化目标量/可转化点击次数
+            result.setDeepConversionsRateAll(result.getValuableClickCountTotal() == 0 ? 0.0 : result.getDeepConversionsCountTotal() / result.getValuableClickCountTotal());
+            result.setDeepConversionsRateDay(value2.getDeepConversionsRate());
+            result.setKeyPageUvTotal(value1.getKeyPageUvTotal() + value2.getKeyPageUv());
+            result.setKeyPageUvDay(value2.getKeyPageUv());
+            result.setOrderCountTotal(value1.getOrderCountTotal() + value2.getOrderCount());
+            result.setOrderCountDay(value2.getOrderCount());
+            result.setFirstDayOrderCountTotal(value1.getFirstDayOrderCountTotal() + value2.getFirstDayOrderCount());
+            result.setFirstDayOrderCountDay(value2.getFirstDayOrderCount());
+            // 广告花费/下单量
+            result.setWebOrderCostAll(result.getOrderCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOrderCountTotal());
+            result.setWebOrderCostDay(value2.getWebOrderCost());
+            // 下单量/点击次数
+            result.setOrderRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getOrderCountTotal() / result.getValidClickCountTotal());
+            result.setOrderRateDay(value2.getOrderRate());
+            result.setOrderAmountTotal(value1.getOrderAmountTotal() + value2.getOrderAmount());
+            result.setOrderAmountDay(value2.getOrderAmount());
+            result.setFirstDayOrderAmountTotal(value1.getFirstDayOrderAmountTotal() + value2.getFirstDayOrderAmount());
+            result.setFirstDayOrderAmountDay(value2.getFirstDayOrderAmount());
+            // 下单金额/下单量
+            result.setOrderUnitPriceAll(result.getOrderCountTotal() == 0 ? 0 : result.getOrderAmountTotal() / result.getOrderCountTotal());
+            result.setOrderUnitPriceDay(value2.getOrderUnitPrice());
+            // 下单金额/广告花费
+            result.setOrderRoiAll(result.getCostTotal() == 0 ? 0.0 : result.getOrderAmountTotal() / result.getCostTotal());
+            result.setOrderRoiDay(value2.getOrderRoi());
+            result.setSignInCountTotal(value1.getSignInCountTotal() + value2.getSignInCount());
+            result.setSignInCountDay(value2.getSignInCount());
+            result.setAddWishlistCountTotal(value1.getAddWishlistCountTotal() + value2.getAddWishlistCount());
+            result.setAddWishlistCountDay(value2.getAddWishlistCount());
+            result.setViewCommodityPageUvTotal(value1.getViewCommodityPageUvTotal() + value2.getViewCommodityPageUv());
+            result.setViewCommodityPageUvDay(value2.getViewCommodityPageUv());
+            result.setPageReservationCountTotal(value1.getPageReservationCountTotal() + value2.getPageReservationCount());
+            result.setPageReservationCountDay(value2.getPageReservationCount());
+
+            // 应该不准,因为跨天的用户无法去重
+            result.setLeadsPurchaseUvTotal(value1.getLeadsPurchaseUvTotal() + value2.getLeadsPurchaseUv());
+            result.setLeadsPurchaseUvDay(value2.getLeadsPurchaseUv());
+            // 广告消耗/首次付费人数
+            result.setLeadsPurchaseCostAll(result.getLeadsPurchaseUvTotal() == 0 ? 0 : result.getCostTotal() / result.getLeadsPurchaseUvTotal());
+            result.setLeadsPurchaseCostDay(value2.getLeadsPurchaseCost());
+            // 首次付费人数/广告点击次数
+            result.setLeadsPurchaseRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getLeadsPurchaseUvTotal() / result.getValidClickCountTotal());
+            result.setLeadsPurchaseRateDay(value2.getLeadsPurchaseRate());
+            result.setScanFollowCountTotal(value1.getScanFollowCountTotal() + value2.getScanFollowCount());
+            result.setScanFollowCountDay(value2.getScanFollowCount());
+            result.setWechatAppRegisterUvTotal(value1.getWechatAppRegisterUvTotal() + value2.getWechatAppRegisterUv());
+            result.setWechatAppRegisterUvDay(value2.getWechatAppRegisterUv());
+            // 广告消耗 / 小游戏注册人数
+            result.setWechatMinigameRegisterCostAll(result.getWechatAppRegisterUvTotal() == 0 ? 0 : result.getCostTotal() / result.getWechatAppRegisterUvTotal());
+            result.setWechatMinigameRegisterCostDay(value2.getWechatMinigameRegisterCost());
+            // 小游戏注册人数 / 广告点击次数
+            result.setWechatMinigameRegisterRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getWechatAppRegisterUvTotal() / result.getValidClickCountTotal());
+            result.setWechatMinigameRegisterRateDay(value2.getWechatMinigameRegisterRate());
+            // 总收益 / 总人数
+            result.setWechatMinigameArpuAll(result.getWechatAppRegisterUvTotal() == 0 ? 0.0 : result.getOrderAmountTotal() / result.getWechatAppRegisterUvTotal());
+            result.setWechatMinigameArpuDay(value2.getWechatMinigameArpu());
+            result.setWechatMinigameRetentionCountTotal(value1.getWechatMinigameRetentionCountTotal() + value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameRetentionCountDay(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameCheckoutCountTotal(value1.getWechatMinigameCheckoutCountTotal() + value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutCountDay(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutAmountTotal(value1.getWechatMinigameCheckoutAmountTotal() + value2.getWechatMinigameCheckoutAmount());
+            result.setWechatMinigameCheckoutAmountDay(value2.getWechatMinigameCheckoutAmount());
+            result.setOfficialAccountFollowCountTotal(value1.getOfficialAccountFollowCountTotal() + value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCountDay(value2.getOfficialAccountFollowCount());
+            // 广告消耗 / 关注次数
+            result.setOfficialAccountFollowCostAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountFollowCostDay(value2.getOfficialAccountFollowCost());
+            // 关注次数 / 点击次数
+            result.setOfficialAccountFollowRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getOfficialAccountFollowCountTotal() / result.getValidClickCountTotal());
+            result.setOfficialAccountFollowRateDay(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountRegisterUserCountTotal(value1.getOfficialAccountRegisterUserCountTotal() + value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterUserCountDay(value2.getOfficialAccountRegisterUserCount());
+            // 公众号内注册人数 / 公众号关注次数
+            result.setOfficialAccountRegisterRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountRegisterUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountRegisterRateDay(value2.getOfficialAccountRegisterRate());
+            // 广告消耗 / 广告注册人数
+            result.setOfficialAccountRegisterCostAll(result.getOfficialAccountRegisterUserCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountRegisterUserCountTotal());
+            result.setOfficialAccountRegisterCostDay(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterAmountTotal(value1.getOfficialAccountRegisterAmountTotal() + value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterAmountDay(value2.getOfficialAccountRegisterAmount());
+            // 注册产生的订单金额累计/广告花费
+            result.setOfficialAccountRegisterRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountRegisterAmountTotal() / result.getCostTotal());
+            result.setOfficialAccountRegisterRoiDay(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountApplyCountTotal(value1.getOfficialAccountApplyCountTotal() + value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyCountDay(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyUserCountTotal(value1.getOfficialAccountApplyUserCountTotal() + value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyUserCountDay(value2.getOfficialAccountApplyUserCount());
+            // 公众号内填单的独立用户数/公众号关注次数
+            result.setOfficialAccountApplyRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountApplyUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountApplyRateDay(value2.getOfficialAccountApplyRate());
+            // 广告花费/广告产生的填单行为数量
+            result.setOfficialAccountApplyCostAll(result.getOfficialAccountApplyUserCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountApplyUserCountTotal());
+            result.setOfficialAccountApplyCostDay(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyAmountTotal(value1.getOfficialAccountApplyAmountTotal() + value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyAmountDay(value2.getOfficialAccountApplyAmount());
+            // 填单产生的订单金额累计/广告花费
+            result.setOfficialAccountApplyRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountApplyAmountTotal() / result.getCostTotal());
+            result.setOfficialAccountApplyRoiDay(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountOrderCountTotal(value1.getOfficialAccountOrderCountTotal() + value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountOrderCountDay(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountFirstDayOrderCountTotal(value1.getOfficialAccountFirstDayOrderCountTotal() + value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountFirstDayOrderCountDay(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountOrderUserCountTotal(value1.getOfficialAccountOrderUserCountTotal() + value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderUserCountDay(value2.getOfficialAccountOrderUserCount());
+            // 公众号内下单独立用户数(UV)/公众号关注次数
+            result.setOfficialAccountOrderRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountOrderUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountOrderRateDay(value2.getOfficialAccountOrderRate());
+            // 广告花费/广告产生的下单行为数量
+            result.setOfficialAccountOrderCostAll(result.getOfficialAccountOrderCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountOrderCountTotal());
+            result.setOfficialAccountOrderCostDay(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderAmountTotal(value1.getOfficialAccountOrderAmountTotal() + value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountOrderAmountDay(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountTotal(value1.getOfficialAccountFirstDayOrderAmountTotal() + value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountDay(value2.getOfficialAccountFirstDayOrderAmount());
+            // 下单产生的订单金额累计/广告花费
+            result.setOfficialAccountOrderRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountOrderAmountTotal() / result.getCostTotal());
+            result.setOfficialAccountOrderRoiDay(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountConsultCountTotal(value1.getOfficialAccountConsultCountTotal() + value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountConsultCountDay(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountReaderCountTotal(value1.getOfficialAccountReaderCountTotal() + value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountReaderCountDay(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountCreditApplyUserCountTotal(value1.getOfficialAccountCreditApplyUserCountTotal() + value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditApplyUserCountDay(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditUserCountTotal(value1.getOfficialAccountCreditUserCountTotal() + value2.getOfficialAccountCreditUserCount());
+            result.setOfficialAccountCreditUserCountDay(value2.getOfficialAccountCreditUserCount());
+            result.setForwardCountTotal(value1.getForwardCountTotal() + value2.getForwardCount());
+            result.setForwardCountDay(value2.getForwardCount());
+            result.setForwardUserCountTotal(value1.getForwardUserCountTotal() + value2.getForwardUserCount());
+            result.setForwardUserCountDay(value2.getForwardUserCount());
+            result.setNoInterestCountTotal(value1.getNoInterestCountTotal() + value2.getNoInterestCount());
+            result.setNoInterestCountDay(value2.getNoInterestCount());
+        }
+        return result;
+    }
+
+    public static PlanStatOfDayDWD byMaxCompute(Record record) {
+        PlanStatOfDayDWD result = new PlanStatOfDayDWD();
+        result.setStatDay(ObjectUtil.toString(record.get("stat_day")));
+        result.setAccountId(ObjectUtil.toLong(record.get("account_id")));
+        result.setCampaignId(ObjectUtil.toLong(record.get("campaign_id")));
+        result.setAgencyAccountId(ObjectUtil.toLong(record.get("agency_account_id")));
+        result.setWechatAccountId(ObjectUtil.toString(record.get("wechat_account_id")));
+        result.setWechatAgencyId(ObjectUtil.toString(record.get("wechat_agency_id")));
+
+        result.setAdGroupMapStr(ObjectUtil.toString(record.get("ad_group_map_str")));
+        result.setAdGroupMap(PlanUtil.parseAdGroupMapStr(result.getAdGroupMapStr()));
+        result.setAdIdsStr(ObjectUtil.toString(record.get("ad_ids_str")));
+        result.setAdIds(PlanUtil.parseAdStr(result.getAdIdsStr()));
+
+        result.setCreateTime(ObjectUtil.toDate(record.get("create_time")));
+        result.setCostDeviationRateTotal(ObjectUtil.toDouble(record.get("cost_deviation_rate_total")));
+        result.setCostDeviationRateDay(ObjectUtil.toDouble(record.get("cost_deviation_rate_day")));
+        result.setCostTotal(ObjectUtil.toLong(record.get("cost_total")));
+        result.setCostDay(ObjectUtil.toLong(record.get("cost_day")));
+        result.setCompensationAmountTotal(ObjectUtil.toLong(record.get("compensation_amount_total")));
+        result.setCompensationAmountDay(ObjectUtil.toLong(record.get("compensation_amount_day")));
+        result.setViewCountTotal(ObjectUtil.toLong(record.get("view_count_total")));
+        result.setViewCountDay(ObjectUtil.toLong(record.get("view_count_day")));
+        result.setThousandDisplayPriceAll(ObjectUtil.toLong(record.get("thousand_display_price_all")));
+        result.setThousandDisplayPriceDay(ObjectUtil.toLong(record.get("thousand_display_price_day")));
+        result.setViewUserCountTotal(ObjectUtil.toLong(record.get("view_user_count_total")));
+        result.setViewUserCountDay(ObjectUtil.toLong(record.get("view_user_count_day")));
+        result.setAvgViewPerUserAll(ObjectUtil.toDouble(record.get("avg_view_per_user_all")));
+        result.setAvgViewPerUserDay(ObjectUtil.toDouble(record.get("avg_view_per_user_day")));
+        result.setValidClickCountTotal(ObjectUtil.toLong(record.get("valid_click_count_total")));
+        result.setValidClickCountDay(ObjectUtil.toLong(record.get("valid_click_count_day")));
+        result.setClickUserCountTotal(ObjectUtil.toLong(record.get("click_user_count_total")));
+        result.setClickUserCountDay(ObjectUtil.toLong(record.get("click_user_count_day")));
+        result.setCtrAll(ObjectUtil.toDouble(record.get("ctr_all")));
+        result.setCtrDay(ObjectUtil.toDouble(record.get("ctr_day")));
+        result.setCpcAll(ObjectUtil.toLong(record.get("cpc_all")));
+        result.setCpcDay(ObjectUtil.toLong(record.get("cpc_day")));
+        result.setValuableClickCountTotal(ObjectUtil.toLong(record.get("valuable_click_count_total")));
+        result.setValuableClickCountDay(ObjectUtil.toLong(record.get("valuable_click_count_day")));
+        result.setValuableClickRateAll(ObjectUtil.toDouble(record.get("valuable_click_rate_all")));
+        result.setValuableClickRateDay(ObjectUtil.toDouble(record.get("valuable_click_rate_day")));
+        result.setValuableClickCostAll(ObjectUtil.toLong(record.get("valuable_click_cost_all")));
+        result.setValuableClickCostDay(ObjectUtil.toLong(record.get("valuable_click_cost_day")));
+        result.setConversionsCountTotal(ObjectUtil.toLong(record.get("conversions_count_total")));
+        result.setConversionsCountDay(ObjectUtil.toLong(record.get("conversions_count_day")));
+        result.setConversionsCostAll(ObjectUtil.toLong(record.get("conversions_cost_all")));
+        result.setConversionsCostDay(ObjectUtil.toLong(record.get("conversions_cost_day")));
+        result.setConversionsRateAll(ObjectUtil.toDouble(record.get("conversions_rate_all")));
+        result.setConversionsRateDay(ObjectUtil.toDouble(record.get("conversions_rate_day")));
+        result.setDeepConversionsCountTotal(ObjectUtil.toLong(record.get("deep_conversions_count_total")));
+        result.setDeepConversionsCountDay(ObjectUtil.toLong(record.get("deep_conversions_count_day")));
+        result.setDeepConversionsCostAll(ObjectUtil.toLong(record.get("deep_conversions_cost_all")));
+        result.setDeepConversionsCostDay(ObjectUtil.toLong(record.get("deep_conversions_cost_day")));
+        result.setDeepConversionsRateAll(ObjectUtil.toDouble(record.get("deep_conversions_rate_all")));
+        result.setDeepConversionsRateDay(ObjectUtil.toDouble(record.get("deep_conversions_rate_day")));
+        result.setKeyPageUvTotal(ObjectUtil.toLong(record.get("key_page_uv_total")));
+        result.setKeyPageUvDay(ObjectUtil.toLong(record.get("key_page_uv_day")));
+        result.setOrderCountTotal(ObjectUtil.toLong(record.get("order_count_total")));
+        result.setOrderCountDay(ObjectUtil.toLong(record.get("order_count_day")));
+        result.setFirstDayOrderCountTotal(ObjectUtil.toLong(record.get("first_day_order_count_total")));
+        result.setFirstDayOrderCountDay(ObjectUtil.toLong(record.get("first_day_order_count_day")));
+        result.setWebOrderCostAll(ObjectUtil.toLong(record.get("web_order_cost_all")));
+        result.setWebOrderCostDay(ObjectUtil.toLong(record.get("web_order_cost_day")));
+        result.setOrderRateAll(ObjectUtil.toDouble(record.get("order_rate_all")));
+        result.setOrderRateDay(ObjectUtil.toDouble(record.get("order_rate_day")));
+        result.setOrderAmountTotal(ObjectUtil.toLong(record.get("order_amount_total")));
+        result.setOrderAmountDay(ObjectUtil.toLong(record.get("order_amount_day")));
+        result.setFirstDayOrderAmountTotal(ObjectUtil.toLong(record.get("first_day_order_amount_total")));
+        result.setFirstDayOrderAmountDay(ObjectUtil.toLong(record.get("first_day_order_amount_day")));
+        result.setOrderUnitPriceAll(ObjectUtil.toLong(record.get("order_unit_price_all")));
+        result.setOrderUnitPriceDay(ObjectUtil.toLong(record.get("order_unit_price_day")));
+        result.setOrderRoiAll(ObjectUtil.toDouble(record.get("order_roi_all")));
+        result.setOrderRoiDay(ObjectUtil.toDouble(record.get("order_roi_day")));
+        result.setSignInCountTotal(ObjectUtil.toLong(record.get("sign_in_count_total")));
+        result.setSignInCountDay(ObjectUtil.toLong(record.get("sign_in_count_day")));
+        result.setAddWishlistCountTotal(ObjectUtil.toLong(record.get("add_wishlist_count_total")));
+        result.setAddWishlistCountDay(ObjectUtil.toLong(record.get("add_wishlist_count_day")));
+        result.setViewCommodityPageUvTotal(ObjectUtil.toLong(record.get("view_commodity_page_uv_total")));
+        result.setViewCommodityPageUvDay(ObjectUtil.toLong(record.get("view_commodity_page_uv_day")));
+        result.setPageReservationCountTotal(ObjectUtil.toLong(record.get("page_reservation_count_total")));
+        result.setPageReservationCountDay(ObjectUtil.toLong(record.get("page_reservation_count_day")));
+        result.setLeadsPurchaseUvTotal(ObjectUtil.toLong(record.get("leads_purchase_uv_total")));
+        result.setLeadsPurchaseUvDay(ObjectUtil.toLong(record.get("leads_purchase_uv_day")));
+        result.setLeadsPurchaseCostAll(ObjectUtil.toLong(record.get("leads_purchase_cost_all")));
+        result.setLeadsPurchaseCostDay(ObjectUtil.toLong(record.get("leads_purchase_cost_day")));
+        result.setLeadsPurchaseRateAll(ObjectUtil.toDouble(record.get("leads_purchase_rate_all")));
+        result.setLeadsPurchaseRateDay(ObjectUtil.toDouble(record.get("leads_purchase_rate_day")));
+        result.setScanFollowCountTotal(ObjectUtil.toLong(record.get("scan_follow_count_total")));
+        result.setScanFollowCountDay(ObjectUtil.toLong(record.get("scan_follow_count_day")));
+        result.setWechatAppRegisterUvTotal(ObjectUtil.toLong(record.get("wechat_app_register_uv_total")));
+        result.setWechatAppRegisterUvDay(ObjectUtil.toLong(record.get("wechat_app_register_uv_day")));
+        result.setWechatMinigameRegisterCostAll(ObjectUtil.toLong(record.get("wechat_minigame_register_cost_all")));
+        result.setWechatMinigameRegisterCostDay(ObjectUtil.toLong(record.get("wechat_minigame_register_cost_day")));
+        result.setWechatMinigameRegisterRateAll(ObjectUtil.toDouble(record.get("wechat_minigame_register_rate_all")));
+        result.setWechatMinigameRegisterRateDay(ObjectUtil.toDouble(record.get("wechat_minigame_register_rate_day")));
+        result.setWechatMinigameArpuAll(ObjectUtil.toDouble(record.get("wechat_minigame_arpu_all")));
+        result.setWechatMinigameArpuDay(ObjectUtil.toDouble(record.get("wechat_minigame_arpu_day")));
+        result.setWechatMinigameRetentionCountTotal(ObjectUtil.toLong(record.get("wechat_minigame_retention_count_total")));
+        result.setWechatMinigameRetentionCountDay(ObjectUtil.toLong(record.get("wechat_minigame_retention_count_day")));
+        result.setWechatMinigameCheckoutCountTotal(ObjectUtil.toLong(record.get("wechat_minigame_checkout_count_total")));
+        result.setWechatMinigameCheckoutCountDay(ObjectUtil.toLong(record.get("wechat_minigame_checkout_count_day")));
+        result.setWechatMinigameCheckoutAmountTotal(ObjectUtil.toLong(record.get("wechat_minigame_checkout_amount_total")));
+        result.setWechatMinigameCheckoutAmountDay(ObjectUtil.toLong(record.get("wechat_minigame_checkout_amount_day")));
+        result.setOfficialAccountFollowCountTotal(ObjectUtil.toLong(record.get("official_account_follow_count_total")));
+        result.setOfficialAccountFollowCountDay(ObjectUtil.toLong(record.get("official_account_follow_count_day")));
+        result.setOfficialAccountFollowCostAll(ObjectUtil.toLong(record.get("official_account_follow_cost_all")));
+        result.setOfficialAccountFollowCostDay(ObjectUtil.toLong(record.get("official_account_follow_cost_day")));
+        result.setOfficialAccountFollowRateAll(ObjectUtil.toDouble(record.get("official_account_follow_rate_all")));
+        result.setOfficialAccountFollowRateDay(ObjectUtil.toDouble(record.get("official_account_follow_rate_day")));
+        result.setOfficialAccountRegisterUserCountTotal(ObjectUtil.toLong(record.get("official_account_register_user_count_total")));
+        result.setOfficialAccountRegisterUserCountDay(ObjectUtil.toLong(record.get("official_account_register_user_count_day")));
+        result.setOfficialAccountRegisterRateAll(ObjectUtil.toDouble(record.get("official_account_register_rate_all")));
+        result.setOfficialAccountRegisterRateDay(ObjectUtil.toDouble(record.get("official_account_register_rate_day")));
+        result.setOfficialAccountRegisterCostAll(ObjectUtil.toLong(record.get("official_account_register_cost_all")));
+        result.setOfficialAccountRegisterCostDay(ObjectUtil.toLong(record.get("official_account_register_cost_day")));
+        result.setOfficialAccountRegisterAmountTotal(ObjectUtil.toLong(record.get("official_account_register_amount_total")));
+        result.setOfficialAccountRegisterAmountDay(ObjectUtil.toLong(record.get("official_account_register_amount_day")));
+        result.setOfficialAccountRegisterRoiAll(ObjectUtil.toLong(record.get("official_account_register_roi_all")));
+        result.setOfficialAccountRegisterRoiDay(ObjectUtil.toLong(record.get("official_account_register_roi_day")));
+        result.setOfficialAccountApplyCountTotal(ObjectUtil.toLong(record.get("official_account_apply_count_total")));
+        result.setOfficialAccountApplyCountDay(ObjectUtil.toLong(record.get("official_account_apply_count_day")));
+        result.setOfficialAccountApplyUserCountTotal(ObjectUtil.toLong(record.get("official_account_apply_user_count_total")));
+        result.setOfficialAccountApplyUserCountDay(ObjectUtil.toLong(record.get("official_account_apply_user_count_day")));
+        result.setOfficialAccountApplyRateAll(ObjectUtil.toDouble(record.get("official_account_apply_rate_all")));
+        result.setOfficialAccountApplyRateDay(ObjectUtil.toDouble(record.get("official_account_apply_rate_day")));
+        result.setOfficialAccountApplyCostAll(ObjectUtil.toLong(record.get("official_account_apply_cost_all")));
+        result.setOfficialAccountApplyCostDay(ObjectUtil.toLong(record.get("official_account_apply_cost_day")));
+        result.setOfficialAccountApplyAmountTotal(ObjectUtil.toLong(record.get("official_account_apply_amount_total")));
+        result.setOfficialAccountApplyAmountDay(ObjectUtil.toLong(record.get("official_account_apply_amount_day")));
+        result.setOfficialAccountApplyRoiAll(ObjectUtil.toLong(record.get("official_account_apply_roi_all")));
+        result.setOfficialAccountApplyRoiDay(ObjectUtil.toLong(record.get("official_account_apply_roi_day")));
+        result.setOfficialAccountOrderCountTotal(ObjectUtil.toLong(record.get("official_account_order_count_total")));
+        result.setOfficialAccountOrderCountDay(ObjectUtil.toLong(record.get("official_account_order_count_day")));
+        result.setOfficialAccountFirstDayOrderCountTotal(ObjectUtil.toLong(record.get("official_account_first_day_order_count_total")));
+        result.setOfficialAccountFirstDayOrderCountDay(ObjectUtil.toLong(record.get("official_account_first_day_order_count_day")));
+        result.setOfficialAccountOrderUserCountTotal(ObjectUtil.toLong(record.get("official_account_order_user_count_total")));
+        result.setOfficialAccountOrderUserCountDay(ObjectUtil.toLong(record.get("official_account_order_user_count_day")));
+        result.setOfficialAccountOrderRateAll(ObjectUtil.toDouble(record.get("official_account_order_rate_all")));
+        result.setOfficialAccountOrderRateDay(ObjectUtil.toDouble(record.get("official_account_order_rate_day")));
+        result.setOfficialAccountOrderCostAll(ObjectUtil.toLong(record.get("official_account_order_cost_all")));
+        result.setOfficialAccountOrderCostDay(ObjectUtil.toLong(record.get("official_account_order_cost_day")));
+        result.setOfficialAccountOrderAmountTotal(ObjectUtil.toLong(record.get("official_account_order_amount_total")));
+        result.setOfficialAccountOrderAmountDay(ObjectUtil.toLong(record.get("official_account_order_amount_day")));
+        result.setOfficialAccountFirstDayOrderAmountTotal(ObjectUtil.toLong(record.get("official_account_first_day_order_amount_total")));
+        result.setOfficialAccountFirstDayOrderAmountDay(ObjectUtil.toLong(record.get("official_account_first_day_order_amount_day")));
+        result.setOfficialAccountOrderRoiAll(ObjectUtil.toLong(record.get("official_account_order_roi_all")));
+        result.setOfficialAccountOrderRoiDay(ObjectUtil.toLong(record.get("official_account_order_roi_day")));
+        result.setOfficialAccountConsultCountTotal(ObjectUtil.toLong(record.get("official_account_consult_count_total")));
+        result.setOfficialAccountConsultCountDay(ObjectUtil.toLong(record.get("official_account_consult_count_day")));
+        result.setOfficialAccountReaderCountTotal(ObjectUtil.toLong(record.get("official_account_reader_count_total")));
+        result.setOfficialAccountReaderCountDay(ObjectUtil.toLong(record.get("official_account_reader_count_day")));
+        result.setOfficialAccountCreditApplyUserCountTotal(ObjectUtil.toLong(record.get("official_account_credit_apply_user_count_total")));
+        result.setOfficialAccountCreditApplyUserCountDay(ObjectUtil.toLong(record.get("official_account_credit_apply_user_count_day")));
+        result.setOfficialAccountCreditUserCountTotal(ObjectUtil.toLong(record.get("official_account_credit_user_count_total")));
+        result.setOfficialAccountCreditUserCountDay(ObjectUtil.toLong(record.get("official_account_credit_user_count_day")));
+        result.setForwardCountTotal(ObjectUtil.toLong(record.get("forward_count_total")));
+        result.setForwardCountDay(ObjectUtil.toLong(record.get("forward_count_day")));
+        result.setForwardUserCountTotal(ObjectUtil.toLong(record.get("forward_user_count_total")));
+        result.setForwardUserCountDay(ObjectUtil.toLong(record.get("forward_user_count_day")));
+        result.setNoInterestCountTotal(ObjectUtil.toLong(record.get("no_interest_count_total")));
+        result.setNoInterestCountDay(ObjectUtil.toLong(record.get("no_interest_count_day")));
+        return result;
+    }
+}

+ 1888 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/PlanStatOfHourDWD.java

@@ -0,0 +1,1888 @@
+package flink.zanxiangnet.ad.monitoring.pojo.entity;
+
+import com.aliyun.odps.data.Record;
+import com.google.gson.annotations.SerializedName;
+import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeColumn;
+import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeTable;
+import flink.zanxiangnet.ad.monitoring.util.ObjectUtil;
+import lombok.Data;
+import org.springframework.beans.BeanUtils;
+
+import java.util.Date;
+
+/**
+ * 广告维度的小时统计数据
+ */
+@Data
+@MaxComputeTable("ad_stat_of_hour_dwd")
+public class PlanStatOfHourDWD {
+
+    /**
+     * 统计的日期(用于 MaxCompute分区)
+     */
+    @MaxComputeColumn(isPartitioned = true)
+    @SerializedName("stat_day")
+    private String statDay;
+
+    /**
+     * 统计的小时
+     */
+    @SerializedName("hour")
+    private Integer hour;
+
+    /**
+     * 腾讯广告应用的账号 id
+     */
+    @SerializedName("account_id")
+    private Long accountId;
+
+    /**
+     * 计划 id
+     */
+    @SerializedName("campaign_id")
+    private Long campaignId;
+
+    /**
+     * 服务商账号 id
+     */
+    @SerializedName("agency_account_id")
+    private Long agencyAccountId;
+
+    /**
+     * 微信账号id
+     */
+    @SerializedName("wechat_account_id")
+    private String wechatAccountId;
+
+    /**
+     * 微信服务商id
+     */
+    @SerializedName("wechat_agency_id")
+    private String wechatAgencyId;
+
+    /**
+     * 广告组 id
+     */
+    @SerializedName("adgroup_id")
+    private Long adgroupId;
+
+    /**
+     * 广告 id
+     */
+    @SerializedName("ad_id")
+    private Long adId;
+
+    /**
+     * 记录创建时间
+     */
+    @SerializedName("create_time")
+    private Date createTime;
+
+    /**
+     * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
+     */
+    @SerializedName("cost_deviation_rate_total")
+    private Double costDeviationRateTotal;
+
+    /**
+     * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
+     */
+    @SerializedName("cost_deviation_rate_day")
+    private Double costDeviationRateDay;
+
+    /**
+     * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
+     */
+    @SerializedName("cost_deviation_rate_hour")
+    private Double costDeviationRateHour;
+
+    /**
+     * 消耗
+     */
+    @SerializedName("cost_total")
+    private Long costTotal;
+
+    /**
+     * 消耗
+     */
+    @SerializedName("cost_day")
+    private Long costDay;
+
+    /**
+     * 消耗
+     */
+    @SerializedName("cost_hour")
+    private Long costHour;
+
+    /**
+     * 赔付金额。智能优化成本保障政策下,广告超成本时的赔付金额。
+     */
+    @SerializedName("compensation_amount_total")
+    private Long compensationAmountTotal;
+
+    /**
+     * 赔付金额。智能优化成本保障政策下,广告超成本时的赔付金额。
+     */
+    @SerializedName("compensation_amount_day")
+    private Long compensationAmountDay;
+
+    /**
+     * 赔付金额。智能优化成本保障政策下,广告超成本时的赔付金额。
+     */
+    @SerializedName("compensation_amount_hour")
+    private Long compensationAmountHour;
+
+    /**
+     * 曝光次数。用户观看广告的次数。
+     */
+    @SerializedName("view_count_total")
+    private Long viewCountTotal;
+
+    /**
+     * 曝光次数。用户观看广告的次数。
+     */
+    @SerializedName("view_count_day")
+    private Long viewCountDay;
+
+    /**
+     * 曝光次数。用户观看广告的次数。
+     */
+    @SerializedName("view_count_hour")
+    private Long viewCountHour;
+
+    /**
+     * 千次曝光成本。平均每千次曝光的花费。
+     */
+    @SerializedName("thousand_display_price_all")
+    private Long thousandDisplayPriceAll;
+
+    /**
+     * 千次曝光成本。平均每千次曝光的花费。
+     */
+    @SerializedName("thousand_display_price_day")
+    private Long thousandDisplayPriceDay;
+
+    /**
+     * 千次曝光成本。平均每千次曝光的花费。
+     */
+    @SerializedName("thousand_display_price_hour")
+    private Long thousandDisplayPriceHour;
+
+    /**
+     * 人均曝光次数。每个用户观看广告的平均次数。
+     */
+    @SerializedName("avg_view_per_user_hour")
+    private Double avgViewPerUserHour;
+
+    /**
+     * 点击次数。用户在广告外层进行点击操作的次数。包括点击图片/视频,及朋友圈广告“文字链、头像、昵称、门店、选择按钮”等所有广告外层区域的点击。
+     */
+    @SerializedName("valid_click_count_total")
+    private Long validClickCountTotal;
+
+    /**
+     * 点击次数。用户在广告外层进行点击操作的次数。包括点击图片/视频,及朋友圈广告“文字链、头像、昵称、门店、选择按钮”等所有广告外层区域的点击。
+     */
+    @SerializedName("valid_click_count_day")
+    private Long validClickCountDay;
+
+    /**
+     * 点击次数。用户在广告外层进行点击操作的次数。包括点击图片/视频,及朋友圈广告“文字链、头像、昵称、门店、选择按钮”等所有广告外层区域的点击。
+     */
+    @SerializedName("valid_click_count_hour")
+    private Long validClickCountHour;
+
+    /**
+     * 点击率。看到广告后执行点击操作的百分比。计算逻辑:广告点击次数/广告曝光次数。
+     */
+    @SerializedName("ctr_all")
+    private Double ctrAll;
+
+    /**
+     * 点击率。看到广告后执行点击操作的百分比。计算逻辑:广告点击次数/广告曝光次数。
+     */
+    @SerializedName("ctr_day")
+    private Double ctrDay;
+
+    /**
+     * 点击率。看到广告后执行点击操作的百分比。计算逻辑:广告点击次数/广告曝光次数。
+     */
+    @SerializedName("ctr_hour")
+    private Double ctrHour;
+
+    /**
+     * 点击均价。一次广告点击的平均花费。计算逻辑:广告花费/广告点击次数。
+     */
+    @SerializedName("cpc_all")
+    private Long cpcAll;
+
+    /**
+     * 点击均价。一次广告点击的平均花费。计算逻辑:广告花费/广告点击次数。
+     */
+    @SerializedName("cpc_day")
+    private Long cpcDay;
+
+    /**
+     * 点击均价。一次广告点击的平均花费。计算逻辑:广告花费/广告点击次数。
+     */
+    @SerializedName("cpc_hour")
+    private Long cpcHour;
+
+    /**
+     * 可转化点击次数。朋友圈:可转化点击是指可能产生转化的外层点击次数。对于“公众号推广”的广告,包括外层的公众号头像、公众号昵称、详情页查看、原生推广页查看; 对于其他类型的广告,包括外层的详情页查看和原生推广页查看。公众号:可转化点击是指可能产生转化的点击次数。
+     */
+    @SerializedName("valuable_click_count_total")
+    private Long valuableClickCountTotal;
+
+    /**
+     * 可转化点击次数。朋友圈:可转化点击是指可能产生转化的外层点击次数。对于“公众号推广”的广告,包括外层的公众号头像、公众号昵称、详情页查看、原生推广页查看; 对于其他类型的广告,包括外层的详情页查看和原生推广页查看。公众号:可转化点击是指可能产生转化的点击次数。
+     */
+    @SerializedName("valuable_click_count_day")
+    private Long valuableClickCountDay;
+
+    /**
+     * 可转化点击次数。朋友圈:可转化点击是指可能产生转化的外层点击次数。对于“公众号推广”的广告,包括外层的公众号头像、公众号昵称、详情页查看、原生推广页查看; 对于其他类型的广告,包括外层的详情页查看和原生推广页查看。公众号:可转化点击是指可能产生转化的点击次数。
+     */
+    @SerializedName("valuable_click_count_hour")
+    private Long valuableClickCountHour;
+
+    /**
+     * 可转化点击率。用户看到广告后执行可转化点击操作的百分比。计算逻辑:广告可转化点击次数/广告曝光次数。
+     */
+    @SerializedName("valuable_click_rate_all")
+    private Double valuableClickRateAll;
+
+    /**
+     * 可转化点击率。用户看到广告后执行可转化点击操作的百分比。计算逻辑:广告可转化点击次数/广告曝光次数。
+     */
+    @SerializedName("valuable_click_rate_day")
+    private Double valuableClickRateDay;
+
+    /**
+     * 可转化点击率。用户看到广告后执行可转化点击操作的百分比。计算逻辑:广告可转化点击次数/广告曝光次数。
+     */
+    @SerializedName("valuable_click_rate_hour")
+    private Double valuableClickRateHour;
+
+    /**
+     * 可转化点击成本。一次可转化点击的平均花费。计算逻辑:广告花费/可转化点击次数。
+     */
+    @SerializedName("valuable_click_cost_all")
+    private Long valuableClickCostAll;
+
+    /**
+     * 可转化点击成本。一次可转化点击的平均花费。计算逻辑:广告花费/可转化点击次数。
+     */
+    @SerializedName("valuable_click_cost_day")
+    private Long valuableClickCostDay;
+
+    /**
+     * 可转化点击成本。一次可转化点击的平均花费。计算逻辑:广告花费/可转化点击次数。
+     */
+    @SerializedName("valuable_click_cost_hour")
+    private Long valuableClickCostHour;
+
+    /**
+     * 转化目标量。「转化目标」的具体数量,代表该广告的转化效果量级。
+     */
+    @SerializedName("conversions_count_total")
+    private Long conversionsCountTotal;
+
+    /**
+     * 转化目标量。「转化目标」的具体数量,代表该广告的转化效果量级。
+     */
+    @SerializedName("conversions_count_day")
+    private Long conversionsCountDay;
+
+    /**
+     * 转化目标量。「转化目标」的具体数量,代表该广告的转化效果量级。
+     */
+    @SerializedName("conversions_count_hour")
+    private Long conversionsCountHour;
+
+    /**
+     * 转化目标成本。广告产生一次转化目标的平均费用。计算逻辑:广告花费/转化目标量。
+     */
+    @SerializedName("conversions_cost_all")
+    private Long conversionsCostAll;
+
+    /**
+     * 转化目标成本。广告产生一次转化目标的平均费用。计算逻辑:广告花费/转化目标量。
+     */
+    @SerializedName("conversions_cost_day")
+    private Long conversionsCostDay;
+
+    /**
+     * 转化目标成本。广告产生一次转化目标的平均费用。计算逻辑:广告花费/转化目标量。
+     */
+    @SerializedName("conversions_cost_hour")
+    private Long conversionsCostHour;
+
+    /**
+     * 目标转化率。朋友圈:转化目标量/可转化点击次数。公众号:转化目标量/点击次数。
+     */
+    @SerializedName("conversions_rate_all")
+    private Double conversionsRateAll;
+
+    /**
+     * 目标转化率。朋友圈:转化目标量/可转化点击次数。公众号:转化目标量/点击次数。
+     */
+    @SerializedName("conversions_rate_day")
+    private Double conversionsRateDay;
+
+    /**
+     * 目标转化率。朋友圈:转化目标量/可转化点击次数。公众号:转化目标量/点击次数。
+     */
+    @SerializedName("conversions_rate_hour")
+    private Double conversionsRateHour;
+
+    /**
+     * 深度转化目标量-灰度中。根据您选择的深度智能优化目标,该广告对应的具体数量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_count_total")
+    private Long deepConversionsCountTotal;
+
+    /**
+     * 深度转化目标量-灰度中。根据您选择的深度智能优化目标,该广告对应的具体数量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_count_day")
+    private Long deepConversionsCountDay;
+
+    /**
+     * 深度转化目标量-灰度中。根据您选择的深度智能优化目标,该广告对应的具体数量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_count_hour")
+    private Long deepConversionsCountHour;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost_all")
+    private Long deepConversionsCostAll;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost_day")
+    private Long deepConversionsCostDay;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost_hour")
+    private Long deepConversionsCostHour;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate_all")
+    private Double deepConversionsRateAll;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate_day")
+    private Double deepConversionsRateDay;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate_hour")
+    private Double deepConversionsRateHour;
+
+    /**
+     * 下单量。用户通过该广告进行商品成交(如下单提交、在线支付)的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_count_total")
+    private Long orderCountTotal;
+
+    /**
+     * 下单量。用户通过该广告进行商品成交(如下单提交、在线支付)的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_count_day")
+    private Long orderCountDay;
+
+    /**
+     * 下单量。用户通过该广告进行商品成交(如下单提交、在线支付)的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_count_hour")
+    private Long orderCountHour;
+
+    /**
+     * 首日新增下单量。广告推广获取的用户,点击广告当日,带来的下单次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_count_total")
+    private Long firstDayOrderCountTotal;
+
+    /**
+     * 首日新增下单量。广告推广获取的用户,点击广告当日,带来的下单次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_count_day")
+    private Long firstDayOrderCountDay;
+
+    /**
+     * 首日新增下单量。广告推广获取的用户,点击广告当日,带来的下单次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_count_hour")
+    private Long firstDayOrderCountHour;
+
+    /**
+     * 下单成本(次数)。产生一次下单的成本。
+     */
+    @SerializedName("web_order_cost_all")
+    private Long webOrderCostAll;
+
+    /**
+     * 下单成本(次数)。产生一次下单的成本。
+     */
+    @SerializedName("web_order_cost_day")
+    private Long webOrderCostDay;
+
+    /**
+     * 下单成本(次数)。产生一次下单的成本。
+     */
+    @SerializedName("web_order_cost_hour")
+    private Long webOrderCostHour;
+
+    /**
+     * 下单率。一次点击到下单的转化率。
+     */
+    @SerializedName("order_rate_all")
+    private Double orderRateAll;
+
+    /**
+     * 下单率。一次点击到下单的转化率。
+     */
+    @SerializedName("order_rate_day")
+    private Double orderRateDay;
+
+    /**
+     * 下单率。一次点击到下单的转化率。
+     */
+    @SerializedName("order_rate_hour")
+    private Double orderRateHour;
+
+    /**
+     * 下单金额。广告带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_amount_total")
+    private Long orderAmountTotal;
+
+    /**
+     * 下单金额。广告带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_amount_day")
+    private Long orderAmountDay;
+
+    /**
+     * 下单金额。广告带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_amount_hour")
+    private Long orderAmountHour;
+
+    /**
+     * 首日新增下单金额。广告推广获取的用户,点击广告当日,带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_amount_total")
+    private Long firstDayOrderAmountTotal;
+
+    /**
+     * 首日新增下单金额。广告推广获取的用户,点击广告当日,带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_amount_day")
+    private Long firstDayOrderAmountDay;
+
+    /**
+     * 首日新增下单金额。广告推广获取的用户,点击广告当日,带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_amount_hour")
+    private Long firstDayOrderAmountHour;
+
+    /**
+     * 下单客单价。下单金额/下单量。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_unit_price_all")
+    private Long orderUnitPriceAll;
+
+    /**
+     * 下单客单价。下单金额/下单量。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_unit_price_day")
+    private Long orderUnitPriceDay;
+
+    /**
+     * 下单客单价。下单金额/下单量。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_unit_price_hour")
+    private Long orderUnitPriceHour;
+
+    /**
+     * 下单ROI。下单金额/广告花费。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_roi_all")
+    private Double orderRoiAll;
+
+    /**
+     * 下单ROI。下单金额/广告花费。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_roi_day")
+    private Double orderRoiDay;
+
+    /**
+     * 下单ROI。下单金额/广告花费。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_roi_hour")
+    private Double orderRoiHour;
+
+    /**
+     * 签收次数。签收从广告主处购买的商品的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("sign_in_count_total")
+    private Long signInCountTotal;
+
+    /**
+     * 签收次数。签收从广告主处购买的商品的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("sign_in_count_day")
+    private Long signInCountDay;
+
+    /**
+     * 签收次数。签收从广告主处购买的商品的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("sign_in_count_hour")
+    private Long signInCountHour;
+
+    /**
+     * 加企业微信客服人数。添加企业微信好友成功的独立用户数。
+     */
+    @SerializedName("scan_follow_count_total")
+    private Long scanFollowCountTotal;
+
+    /**
+     * 加企业微信客服人数。添加企业微信好友成功的独立用户数。
+     */
+    @SerializedName("scan_follow_count_day")
+    private Long scanFollowCountDay;
+
+    /**
+     * 加企业微信客服人数。添加企业微信好友成功的独立用户数。
+     */
+    @SerializedName("scan_follow_count_hour")
+    private Long scanFollowCountHour;
+
+    /**
+     * 小游戏注册人数。通过广告首次登录小游戏的独立用户数。
+     */
+    @SerializedName("wechat_app_register_uv_total")
+    private Long wechatAppRegisterUvTotal;
+
+    /**
+     * 小游戏注册人数。通过广告首次登录小游戏的独立用户数。
+     */
+    @SerializedName("wechat_app_register_uv_day")
+    private Long wechatAppRegisterUvDay;
+
+    /**
+     * 小游戏注册人数。通过广告首次登录小游戏的独立用户数。
+     */
+    @SerializedName("wechat_app_register_uv_hour")
+    private Long wechatAppRegisterUvHour;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @SerializedName("wechat_minigame_register_cost_all")
+    private Long wechatMinigameRegisterCostAll;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @SerializedName("wechat_minigame_register_cost_day")
+    private Long wechatMinigameRegisterCostDay;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @SerializedName("wechat_minigame_register_cost_hour")
+    private Long wechatMinigameRegisterCostHour;
+
+    /**
+     * 小游戏注册率。一次点击到小游戏注册的转化率。
+     */
+    @SerializedName("wechat_minigame_register_rate_all")
+    private Double wechatMinigameRegisterRateAll;
+
+    /**
+     * 小游戏注册率。一次点击到小游戏注册的转化率。
+     */
+    @SerializedName("wechat_minigame_register_rate_day")
+    private Double wechatMinigameRegisterRateDay;
+
+    /**
+     * 小游戏注册率。一次点击到小游戏注册的转化率。
+     */
+    @SerializedName("wechat_minigame_register_rate_hour")
+    private Double wechatMinigameRegisterRateHour;
+
+    /**
+     * 首日新增广告ARPU。广告带来的注册用户,在注册当日,产生的平均广告变现收入。注:该指标天更新,可以查看昨天及以前的数据。
+     */
+    @SerializedName("wechat_minigame_arpu_all")
+    private Double wechatMinigameArpuAll;
+
+    /**
+     * 首日新增广告ARPU。广告带来的注册用户,在注册当日,产生的平均广告变现收入。注:该指标天更新,可以查看昨天及以前的数据。
+     */
+    @SerializedName("wechat_minigame_arpu_day")
+    private Double wechatMinigameArpuDay;
+
+    /**
+     * 首日新增广告ARPU。广告带来的注册用户,在注册当日,产生的平均广告变现收入。注:该指标天更新,可以查看昨天及以前的数据。
+     */
+    @SerializedName("wechat_minigame_arpu_hour")
+    private Double wechatMinigameArpuHour;
+
+    /**
+     * 小游戏次留人数。通过广告首次登录小游戏,并在第二天再次登录的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_retention_count_total")
+    private Long wechatMinigameRetentionCountTotal;
+
+    /**
+     * 小游戏次留人数。通过广告首次登录小游戏,并在第二天再次登录的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_retention_count_day")
+    private Long wechatMinigameRetentionCountDay;
+
+    /**
+     * 小游戏次留人数。通过广告首次登录小游戏,并在第二天再次登录的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_retention_count_hour")
+    private Long wechatMinigameRetentionCountHour;
+
+    /**
+     * 小游戏付费次数。通过广告进入小游戏并完成付费的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_count_total")
+    private Long wechatMinigameCheckoutCountTotal;
+
+    /**
+     * 小游戏付费次数。通过广告进入小游戏并完成付费的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_count_day")
+    private Long wechatMinigameCheckoutCountDay;
+
+    /**
+     * 小游戏付费次数。通过广告进入小游戏并完成付费的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_count_hour")
+    private Long wechatMinigameCheckoutCountHour;
+
+    /**
+     * 小游戏付费金额。通过广告进入小游戏并完成付费的金额。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_amount_total")
+    private Long wechatMinigameCheckoutAmountTotal;
+
+    /**
+     * 小游戏付费金额。通过广告进入小游戏并完成付费的金额。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_amount_day")
+    private Long wechatMinigameCheckoutAmountDay;
+
+    /**
+     * 小游戏付费金额。通过广告进入小游戏并完成付费的金额。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_amount_hour")
+    private Long wechatMinigameCheckoutAmountHour;
+
+    /**
+     * 公众号关注次数。用户通过广告关注公众号成功的次数。
+     */
+    @SerializedName("official_account_follow_count_total")
+    private Long officialAccountFollowCountTotal;
+
+    /**
+     * 公众号关注次数。用户通过广告关注公众号成功的次数。
+     */
+    @SerializedName("official_account_follow_count_day")
+    private Long officialAccountFollowCountDay;
+
+    /**
+     * 公众号关注次数。用户通过广告关注公众号成功的次数。
+     */
+    @SerializedName("official_account_follow_count_hour")
+    private Long officialAccountFollowCountHour;
+
+    /**
+     * 公众号关注率。一次点击到公众号关注的转化率。
+     */
+    @SerializedName("official_account_follow_rate_all")
+    private Double officialAccountFollowRateAll;
+
+    /**
+     * 公众号关注率。一次点击到公众号关注的转化率。
+     */
+    @SerializedName("official_account_follow_rate_day")
+    private Double officialAccountFollowRateDay;
+
+    /**
+     * 公众号关注率。一次点击到公众号关注的转化率。
+     */
+    @SerializedName("official_account_follow_rate_hour")
+    private Double officialAccountFollowRateHour;
+
+    /**
+     * 公众号内注册人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的注册行为的人数(UV)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_user_count_total")
+    private Long officialAccountRegisterUserCountTotal;
+
+    /**
+     * 公众号内注册人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的注册行为的人数(UV)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_user_count_day")
+    private Long officialAccountRegisterUserCountDay;
+
+    /**
+     * 公众号内注册人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的注册行为的人数(UV)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_user_count_hour")
+    private Long officialAccountRegisterUserCountHour;
+
+    /**
+     * 公众号内注册比例。公众号内注册独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_rate_all")
+    private Double officialAccountRegisterRateAll;
+
+    /**
+     * 公众号内注册比例。公众号内注册独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_rate_day")
+    private Double officialAccountRegisterRateDay;
+
+    /**
+     * 公众号内注册比例。公众号内注册独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_rate_hour")
+    private Double officialAccountRegisterRateHour;
+
+    /**
+     * 公众号内注册成本。广告花费/广告产生的注册行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_cost_all")
+    private Long officialAccountRegisterCostAll;
+
+    /**
+     * 公众号内注册成本。广告花费/广告产生的注册行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_cost_day")
+    private Long officialAccountRegisterCostDay;
+
+    /**
+     * 公众号内注册成本。广告花费/广告产生的注册行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_cost_hour")
+    private Long officialAccountRegisterCostHour;
+
+    /**
+     * 公众号内注册订单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的订单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_amount_total")
+    private Long officialAccountRegisterAmountTotal;
+
+    /**
+     * 公众号内注册订单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的订单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_amount_day")
+    private Long officialAccountRegisterAmountDay;
+
+    /**
+     * 公众号内注册订单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的订单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_amount_hour")
+    private Long officialAccountRegisterAmountHour;
+
+    /**
+     * 公众号内注册ROI。注册产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_roi_all")
+    private Long officialAccountRegisterRoiAll;
+
+    /**
+     * 公众号内注册ROI。注册产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_roi_day")
+    private Long officialAccountRegisterRoiDay;
+
+    /**
+     * 公众号内注册ROI。注册产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_roi_hour")
+    private Long officialAccountRegisterRoiHour;
+
+    /**
+     * 公众号内填单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_count_total")
+    private Long officialAccountApplyCountTotal;
+
+    /**
+     * 公众号内填单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_count_day")
+    private Long officialAccountApplyCountDay;
+
+    /**
+     * 公众号内填单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_count_hour")
+    private Long officialAccountApplyCountHour;
+
+    /**
+     * 公众号内填单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_user_count_total")
+    private Long officialAccountApplyUserCountTotal;
+
+    /**
+     * 公众号内填单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_user_count_day")
+    private Long officialAccountApplyUserCountDay;
+
+    /**
+     * 公众号内填单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_user_count_hour")
+    private Long officialAccountApplyUserCountHour;
+
+    /**
+     * 公众号内填单比例。公众号内填单的独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_rate_all")
+    private Double officialAccountApplyRateAll;
+
+    /**
+     * 公众号内填单比例。公众号内填单的独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_rate_day")
+    private Double officialAccountApplyRateDay;
+
+    /**
+     * 公众号内填单比例。公众号内填单的独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_rate_hour")
+    private Double officialAccountApplyRateHour;
+
+    /**
+     * 公众号内填单成本。广告花费/广告产生的填单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_cost_all")
+    private Long officialAccountApplyCostAll;
+
+    /**
+     * 公众号内填单成本。广告花费/广告产生的填单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_cost_day")
+    private Long officialAccountApplyCostDay;
+
+    /**
+     * 公众号内填单成本。广告花费/广告产生的填单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_cost_hour")
+    private Long officialAccountApplyCostHour;
+
+    /**
+     * 公众号内填单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_amount_total")
+    private Long officialAccountApplyAmountTotal;
+
+    /**
+     * 公众号内填单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_amount_day")
+    private Long officialAccountApplyAmountDay;
+
+    /**
+     * 公众号内填单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_amount_hour")
+    private Long officialAccountApplyAmountHour;
+
+    /**
+     * 公众号内填单ROI。填单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_roi_all")
+    private Long officialAccountApplyRoiAll;
+
+    /**
+     * 公众号内填单ROI。填单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_roi_day")
+    private Long officialAccountApplyRoiDay;
+
+    /**
+     * 公众号内填单ROI。填单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_roi_hour")
+    private Long officialAccountApplyRoiHour;
+
+    /**
+     * 公众号内下单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_count_total")
+    private Long officialAccountOrderCountTotal;
+
+    /**
+     * 公众号内下单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_count_day")
+    private Long officialAccountOrderCountDay;
+
+    /**
+     * 公众号内下单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_count_hour")
+    private Long officialAccountOrderCountHour;
+
+    /**
+     * 首日公众号内下单次数。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为数量。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_count_total")
+    private Long officialAccountFirstDayOrderCountTotal;
+
+    /**
+     * 首日公众号内下单次数。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为数量。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_count_day")
+    private Long officialAccountFirstDayOrderCountDay;
+
+    /**
+     * 首日公众号内下单次数。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为数量。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_count_hour")
+    private Long officialAccountFirstDayOrderCountHour;
+
+    /**
+     * 公众号内下单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_user_count_total")
+    private Long officialAccountOrderUserCountTotal;
+
+    /**
+     * 公众号内下单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_user_count_day")
+    private Long officialAccountOrderUserCountDay;
+
+    /**
+     * 公众号内下单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_user_count_hour")
+    private Long officialAccountOrderUserCountHour;
+
+    /**
+     * 公众号内下单比例。公众号内下单独立用户数(UV)/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_rate_all")
+    private Double officialAccountOrderRateAll;
+
+    /**
+     * 公众号内下单比例。公众号内下单独立用户数(UV)/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_rate_day")
+    private Double officialAccountOrderRateDay;
+
+    /**
+     * 公众号内下单比例。公众号内下单独立用户数(UV)/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_rate_hour")
+    private Double officialAccountOrderRateHour;
+
+    /**
+     * 公众号内下单成本。广告花费/广告产生的下单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_cost_all")
+    private Long officialAccountOrderCostAll;
+
+    /**
+     * 公众号内下单成本。广告花费/广告产生的下单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_cost_day")
+    private Long officialAccountOrderCostDay;
+
+    /**
+     * 公众号内下单成本。广告花费/广告产生的下单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_cost_hour")
+    private Long officialAccountOrderCostHour;
+
+    /**
+     * 公众号内下单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_amount_total")
+    private Long officialAccountOrderAmountTotal;
+
+    /**
+     * 公众号内下单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_amount_day")
+    private Long officialAccountOrderAmountDay;
+
+    /**
+     * 公众号内下单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_amount_hour")
+    private Long officialAccountOrderAmountHour;
+
+    /**
+     * 首日公众号内下单金额。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_amount_total")
+    private Long officialAccountFirstDayOrderAmountTotal;
+
+    /**
+     * 首日公众号内下单金额。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_amount_day")
+    private Long officialAccountFirstDayOrderAmountDay;
+
+    /**
+     * 首日公众号内下单金额。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_amount_hour")
+    private Long officialAccountFirstDayOrderAmountHour;
+
+    /**
+     * 公众号内下单ROI。下单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_roi_all")
+    private Long officialAccountOrderRoiAll;
+
+    /**
+     * 公众号内下单ROI。下单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_roi_day")
+    private Long officialAccountOrderRoiDay;
+
+    /**
+     * 公众号内下单ROI。下单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_roi_hour")
+    private Long officialAccountOrderRoiHour;
+
+    /**
+     * 公众号内发消息人数。用户关注公众号后,在公众号对话框内发送消息的独立用户数。
+     */
+    @SerializedName("official_account_consult_count_total")
+    private Long officialAccountConsultCountTotal;
+
+    /**
+     * 公众号内发消息人数。用户关注公众号后,在公众号对话框内发送消息的独立用户数。
+     */
+    @SerializedName("official_account_consult_count_day")
+    private Long officialAccountConsultCountDay;
+
+    /**
+     * 公众号内发消息人数。用户关注公众号后,在公众号对话框内发送消息的独立用户数。
+     */
+    @SerializedName("official_account_consult_count_hour")
+    private Long officialAccountConsultCountHour;
+
+    /**
+     * 阅读粉丝量。近3日新增的粉丝中产生阅读行为的用户数。
+     */
+    @SerializedName("official_account_reader_count_total")
+    private Long officialAccountReaderCountTotal;
+
+    /**
+     * 阅读粉丝量。近3日新增的粉丝中产生阅读行为的用户数。
+     */
+    @SerializedName("official_account_reader_count_day")
+    private Long officialAccountReaderCountDay;
+
+    /**
+     * 阅读粉丝量。近3日新增的粉丝中产生阅读行为的用户数。
+     */
+    @SerializedName("official_account_reader_count_hour")
+    private Long officialAccountReaderCountHour;
+
+    /**
+     * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_apply_user_count_total")
+    private Long officialAccountCreditApplyUserCountTotal;
+
+    /**
+     * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_apply_user_count_day")
+    private Long officialAccountCreditApplyUserCountDay;
+
+    /**
+     * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_apply_user_count_hour")
+    private Long officialAccountCreditApplyUserCountHour;
+
+    /**
+     * 公众号内授信人数。在公众号内完整提交贷款申请资料,并通过放款方的资质审核的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_user_count_total")
+    private Long officialAccountCreditUserCountTotal;
+
+    /**
+     * 公众号内授信人数。在公众号内完整提交贷款申请资料,并通过放款方的资质审核的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_user_count_day")
+    private Long officialAccountCreditUserCountDay;
+
+    /**
+     * 公众号内授信人数。在公众号内完整提交贷款申请资料,并通过放款方的资质审核的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_user_count_hour")
+    private Long officialAccountCreditUserCountHour;
+
+    /**
+     * 广告分享次数。用户将广告落地页分享给好友和朋友圈的次数。
+     */
+    @SerializedName("forward_count_total")
+    private Long forwardCountTotal;
+
+    /**
+     * 广告分享次数。用户将广告落地页分享给好友和朋友圈的次数。
+     */
+    @SerializedName("forward_count_day")
+    private Long forwardCountDay;
+
+    /**
+     * 广告分享次数。用户将广告落地页分享给好友和朋友圈的次数。
+     */
+    @SerializedName("forward_count_hour")
+    private Long forwardCountHour;
+
+    /**
+     * 广告分享人数。将广告落地页分享给好友和朋友圈的独立用户数。
+     */
+    @SerializedName("forward_user_count_total")
+    private Long forwardUserCountTotal;
+
+    /**
+     * 广告分享人数。将广告落地页分享给好友和朋友圈的独立用户数。
+     */
+    @SerializedName("forward_user_count_day")
+    private Long forwardUserCountDay;
+
+    /**
+     * 广告分享人数。将广告落地页分享给好友和朋友圈的独立用户数。
+     */
+    @SerializedName("forward_user_count_hour")
+    private Long forwardUserCountHour;
+
+    /**
+     * 不感兴趣点击次数。用户点击“不感兴趣”的次数。
+     */
+    @SerializedName("no_interest_count_total")
+    private Long noInterestCountTotal;
+
+    /**
+     * 不感兴趣点击次数。用户点击“不感兴趣”的次数。
+     */
+    @SerializedName("no_interest_count_day")
+    private Long noInterestCountDay;
+
+    /**
+     * 不感兴趣点击次数。用户点击“不感兴趣”的次数。
+     */
+    @SerializedName("no_interest_count_hour")
+    private Long noInterestCountHour;
+
+    public static PlanStatOfHourDWD byODS(AdDataOfHourODS adODS) {
+        PlanStatOfHourDWD adStatOfHour = new PlanStatOfHourDWD();
+        adStatOfHour.setStatDay(adODS.getStatDay());
+        adStatOfHour.setHour(adODS.getHour());
+        adStatOfHour.setAccountId(adODS.getAccountId());
+        adStatOfHour.setCampaignId(adODS.getCampaignId());
+        adStatOfHour.setAgencyAccountId(adODS.getAgencyAccountId());
+        adStatOfHour.setWechatAccountId(adODS.getWechatAccountId());
+        adStatOfHour.setWechatAgencyId(adODS.getWechatAgencyId());
+        adStatOfHour.setAdgroupId(adODS.getAdgroupId());
+        adStatOfHour.setAdId(adODS.getAdId());
+        adStatOfHour.setCostDeviationRateHour(adODS.getCostDeviationRate());
+        adStatOfHour.setCostHour(adODS.getCost());
+        adStatOfHour.setCompensationAmountHour(adODS.getCompensationAmount());
+        adStatOfHour.setViewCountHour(adODS.getViewCount());
+        adStatOfHour.setThousandDisplayPriceHour(adODS.getThousandDisplayPrice());
+        adStatOfHour.setAvgViewPerUserHour(adODS.getAvgViewPerUser());
+        adStatOfHour.setValidClickCountHour(adODS.getValidClickCount());
+        adStatOfHour.setCtrHour(adODS.getCtr());
+        adStatOfHour.setCpcHour(adODS.getCpc());
+        adStatOfHour.setValuableClickCountHour(adODS.getValuableClickCount());
+        adStatOfHour.setValuableClickRateHour(adODS.getValuableClickRate());
+        adStatOfHour.setValuableClickCostHour(adODS.getValuableClickCost());
+        adStatOfHour.setConversionsCountHour(adODS.getConversionsCount());
+        adStatOfHour.setConversionsCostHour(adODS.getConversionsCost());
+        adStatOfHour.setConversionsRateHour(adODS.getConversionsRate());
+        adStatOfHour.setDeepConversionsCountHour(adODS.getDeepConversionsCount());
+        adStatOfHour.setDeepConversionsCostHour(adODS.getDeepConversionsCost());
+        adStatOfHour.setDeepConversionsRateHour(adODS.getDeepConversionsRate());
+        adStatOfHour.setOrderCountHour(adODS.getOrderCount());
+        adStatOfHour.setFirstDayOrderCountHour(adODS.getFirstDayOrderCount());
+        adStatOfHour.setWebOrderCostHour(adODS.getWebOrderCost());
+        adStatOfHour.setOrderRateHour(adODS.getOrderRate());
+        adStatOfHour.setOrderAmountHour(adODS.getOrderAmount());
+        adStatOfHour.setFirstDayOrderAmountHour(adODS.getFirstDayOrderAmount());
+        adStatOfHour.setOrderUnitPriceHour(adODS.getOrderUnitPrice());
+        adStatOfHour.setOrderRoiHour(adODS.getOrderRoi());
+        adStatOfHour.setSignInCountHour(adODS.getSignInCount());
+        adStatOfHour.setScanFollowCountHour(adODS.getScanFollowCount());
+        adStatOfHour.setWechatAppRegisterUvHour(adODS.getWechatAppRegisterUv());
+        adStatOfHour.setWechatMinigameRegisterCostHour(adODS.getWechatMinigameRegisterCost());
+        adStatOfHour.setWechatMinigameRegisterRateHour(adODS.getWechatMinigameRegisterRate());
+        adStatOfHour.setWechatMinigameArpuHour(adODS.getWechatMinigameArpu());
+        adStatOfHour.setWechatMinigameRetentionCountHour(adODS.getWechatMinigameRetentionCount());
+        adStatOfHour.setWechatMinigameCheckoutCountHour(adODS.getWechatMinigameCheckoutCount());
+        adStatOfHour.setWechatMinigameCheckoutAmountHour(adODS.getWechatMinigameCheckoutAmount());
+        adStatOfHour.setOfficialAccountFollowCountHour(adODS.getOfficialAccountFollowCount());
+        adStatOfHour.setOfficialAccountFollowRateHour(adODS.getOfficialAccountFollowRate());
+        adStatOfHour.setOfficialAccountRegisterUserCountHour(adODS.getOfficialAccountRegisterUserCount());
+        adStatOfHour.setOfficialAccountRegisterRateHour(adODS.getOfficialAccountRegisterRate());
+        adStatOfHour.setOfficialAccountRegisterCostHour(adODS.getOfficialAccountRegisterCost());
+        adStatOfHour.setOfficialAccountRegisterAmountHour(adODS.getOfficialAccountRegisterAmount());
+        adStatOfHour.setOfficialAccountRegisterRoiHour(adODS.getOfficialAccountRegisterRoi());
+        adStatOfHour.setOfficialAccountApplyCountHour(adODS.getOfficialAccountApplyCount());
+        adStatOfHour.setOfficialAccountApplyUserCountHour(adODS.getOfficialAccountApplyUserCount());
+        adStatOfHour.setOfficialAccountApplyRateHour(adODS.getOfficialAccountApplyRate());
+        adStatOfHour.setOfficialAccountApplyCostHour(adODS.getOfficialAccountApplyCost());
+        adStatOfHour.setOfficialAccountApplyAmountHour(adODS.getOfficialAccountApplyAmount());
+        adStatOfHour.setOfficialAccountApplyRoiHour(adODS.getOfficialAccountApplyRoi());
+        adStatOfHour.setOfficialAccountOrderCountHour(adODS.getOfficialAccountOrderCount());
+        adStatOfHour.setOfficialAccountFirstDayOrderCountHour(adODS.getOfficialAccountFirstDayOrderCount());
+        adStatOfHour.setOfficialAccountOrderUserCountHour(adODS.getOfficialAccountOrderUserCount());
+        adStatOfHour.setOfficialAccountOrderRateHour(adODS.getOfficialAccountOrderRate());
+        adStatOfHour.setOfficialAccountOrderCostHour(adODS.getOfficialAccountOrderCost());
+        adStatOfHour.setOfficialAccountOrderAmountHour(adODS.getOfficialAccountOrderAmount());
+        adStatOfHour.setOfficialAccountFirstDayOrderAmountHour(adODS.getOfficialAccountFirstDayOrderAmount());
+        adStatOfHour.setOfficialAccountOrderRoiHour(adODS.getOfficialAccountOrderRoi());
+        adStatOfHour.setOfficialAccountConsultCountHour(adODS.getOfficialAccountConsultCount());
+        adStatOfHour.setOfficialAccountReaderCountHour(adODS.getOfficialAccountReaderCount());
+        adStatOfHour.setOfficialAccountCreditApplyUserCountHour(adODS.getOfficialAccountCreditApplyUserCount());
+        adStatOfHour.setOfficialAccountCreditUserCountHour(adODS.getOfficialAccountCreditUserCount());
+        adStatOfHour.setForwardCountHour(adODS.getForwardCount());
+        adStatOfHour.setForwardUserCountHour(adODS.getForwardUserCount());
+        adStatOfHour.setNoInterestCountHour(adODS.getNoInterestCount());
+        return adStatOfHour;
+    }
+
+    public static PlanStatOfHourDWD reduce(PlanStatOfHourDWD value1, AdDataOfHourODS value2, long createTime) {
+        PlanStatOfHourDWD result = new PlanStatOfHourDWD();
+        BeanUtils.copyProperties(result, value2);
+        result.setCreateTime(new Date(createTime));
+        if (value1 == null) {
+            result.setCompensationAmountTotal(value2.getCompensationAmount());
+            result.setCompensationAmountDay(value2.getCompensationAmount());
+            result.setCompensationAmountHour(value2.getCompensationAmount());
+            result.setViewCountTotal(value2.getViewCount());
+            result.setViewCountDay(value2.getViewCount());
+            result.setViewCountHour(value2.getViewCount());
+            result.setThousandDisplayPriceAll(value2.getThousandDisplayPrice());
+            result.setThousandDisplayPriceDay(value2.getThousandDisplayPrice());
+            result.setThousandDisplayPriceHour(value2.getThousandDisplayPrice());
+            result.setAvgViewPerUserHour(value2.getAvgViewPerUser());
+            result.setValidClickCountTotal(value2.getValidClickCount());
+            result.setValidClickCountDay(value2.getValidClickCount());
+            result.setValidClickCountHour(value2.getValidClickCount());
+            result.setCtrAll(value2.getCtr());
+            result.setCtrDay(value2.getCtr());
+            result.setCtrHour(value2.getCtr());
+            result.setCpcAll(value2.getCpc());
+            result.setCpcDay(value2.getCpc());
+            result.setCpcHour(value2.getCpc());
+            result.setValuableClickCountTotal(value2.getValuableClickCount());
+            result.setValuableClickCountDay(value2.getValuableClickCount());
+            result.setValuableClickCountHour(value2.getValuableClickCount());
+            result.setValuableClickRateAll(value2.getValuableClickRate());
+            result.setValuableClickRateDay(value2.getValuableClickRate());
+            result.setValuableClickRateHour(value2.getValuableClickRate());
+            result.setValuableClickCostAll(value2.getValuableClickCost());
+            result.setValuableClickCostDay(value2.getValuableClickCost());
+            result.setValuableClickCostHour(value2.getValuableClickCost());
+            result.setConversionsCountTotal(value2.getConversionsCount());
+            result.setConversionsCountDay(value2.getConversionsCount());
+            result.setConversionsCountHour(value2.getConversionsCount());
+            result.setConversionsCostAll(value2.getConversionsCost());
+            result.setConversionsCostDay(value2.getConversionsCost());
+            result.setConversionsCostHour(value2.getConversionsCost());
+            result.setConversionsRateAll(value2.getConversionsRate());
+            result.setConversionsRateDay(value2.getConversionsRate());
+            result.setConversionsRateHour(value2.getConversionsRate());
+            result.setDeepConversionsCountTotal(value2.getDeepConversionsCount());
+            result.setDeepConversionsCountDay(value2.getDeepConversionsCount());
+            result.setDeepConversionsCountHour(value2.getDeepConversionsCount());
+            result.setDeepConversionsCostAll(value2.getDeepConversionsCost());
+            result.setDeepConversionsCostDay(value2.getDeepConversionsCost());
+            result.setDeepConversionsCostHour(value2.getDeepConversionsCost());
+            result.setDeepConversionsRateAll(value2.getDeepConversionsRate());
+            result.setDeepConversionsRateDay(value2.getDeepConversionsRate());
+            result.setDeepConversionsRateHour(value2.getDeepConversionsRate());
+            result.setOrderCountTotal(value2.getOrderCount());
+            result.setOrderCountDay(value2.getOrderCount());
+            result.setOrderCountHour(value2.getOrderCount());
+            result.setFirstDayOrderCountTotal(value2.getFirstDayOrderCount());
+            result.setFirstDayOrderCountDay(value2.getFirstDayOrderCount());
+            result.setFirstDayOrderCountHour(value2.getFirstDayOrderCount());
+            result.setWebOrderCostAll(value2.getWebOrderCost());
+            result.setWebOrderCostDay(value2.getWebOrderCost());
+            result.setWebOrderCostHour(value2.getWebOrderCost());
+            result.setOrderRateAll(value2.getOrderRate());
+            result.setOrderRateDay(value2.getOrderRate());
+            result.setOrderRateHour(value2.getOrderRate());
+            result.setOrderAmountTotal(value2.getOrderAmount());
+            result.setOrderAmountDay(value2.getOrderAmount());
+            result.setOrderAmountHour(value2.getOrderAmount());
+            result.setFirstDayOrderAmountTotal(value2.getFirstDayOrderAmount());
+            result.setFirstDayOrderAmountDay(value2.getFirstDayOrderAmount());
+            result.setFirstDayOrderAmountHour(value2.getFirstDayOrderAmount());
+            result.setOrderUnitPriceAll(value2.getOrderUnitPrice());
+            result.setOrderUnitPriceDay(value2.getOrderUnitPrice());
+            result.setOrderUnitPriceHour(value2.getOrderUnitPrice());
+            result.setOrderRoiAll(value2.getOrderRoi());
+            result.setOrderRoiDay(value2.getOrderRoi());
+            result.setOrderRoiHour(value2.getOrderRoi());
+            result.setSignInCountTotal(value2.getSignInCount());
+            result.setSignInCountDay(value2.getSignInCount());
+            result.setSignInCountHour(value2.getSignInCount());
+            result.setScanFollowCountTotal(value2.getScanFollowCount());
+            result.setScanFollowCountDay(value2.getScanFollowCount());
+            result.setScanFollowCountHour(value2.getScanFollowCount());
+            result.setWechatAppRegisterUvTotal(value2.getWechatAppRegisterUv());
+            result.setWechatAppRegisterUvDay(value2.getWechatAppRegisterUv());
+            result.setWechatAppRegisterUvHour(value2.getWechatAppRegisterUv());
+            result.setWechatMinigameRegisterCostAll(value2.getWechatMinigameRegisterCost());
+            result.setWechatMinigameRegisterCostDay(value2.getWechatMinigameRegisterCost());
+            result.setWechatMinigameRegisterCostHour(value2.getWechatMinigameRegisterCost());
+            result.setWechatMinigameRegisterRateAll(value2.getWechatMinigameRegisterRate());
+            result.setWechatMinigameRegisterRateDay(value2.getWechatMinigameRegisterRate());
+            result.setWechatMinigameRegisterRateHour(value2.getWechatMinigameRegisterRate());
+            result.setWechatMinigameArpuAll(value2.getWechatMinigameArpu());
+            result.setWechatMinigameArpuDay(value2.getWechatMinigameArpu());
+            result.setWechatMinigameArpuHour(value2.getWechatMinigameArpu());
+            result.setWechatMinigameRetentionCountTotal(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameRetentionCountDay(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameRetentionCountHour(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameCheckoutCountTotal(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutCountDay(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutCountHour(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutAmountTotal(value2.getWechatMinigameCheckoutAmount());
+            result.setWechatMinigameCheckoutAmountDay(value2.getWechatMinigameCheckoutAmount());
+            result.setWechatMinigameCheckoutAmountHour(value2.getWechatMinigameCheckoutAmount());
+            result.setOfficialAccountFollowCountTotal(value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCountDay(value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCountHour(value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowRateAll(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountFollowRateDay(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountFollowRateHour(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountRegisterUserCountTotal(value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterUserCountDay(value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterUserCountHour(value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterRateAll(value2.getOfficialAccountRegisterRate());
+            result.setOfficialAccountRegisterRateDay(value2.getOfficialAccountRegisterRate());
+            result.setOfficialAccountRegisterRateHour(value2.getOfficialAccountRegisterRate());
+            result.setOfficialAccountRegisterCostAll(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterCostDay(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterCostHour(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterAmountTotal(value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterAmountDay(value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterAmountHour(value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterRoiAll(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountRegisterRoiDay(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountRegisterRoiHour(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountApplyCountTotal(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyCountDay(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyCountHour(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyUserCountTotal(value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyUserCountDay(value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyUserCountHour(value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyRateAll(value2.getOfficialAccountApplyRate());
+            result.setOfficialAccountApplyRateDay(value2.getOfficialAccountApplyRate());
+            result.setOfficialAccountApplyRateHour(value2.getOfficialAccountApplyRate());
+            result.setOfficialAccountApplyCostAll(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyCostDay(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyCostHour(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyAmountTotal(value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyAmountDay(value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyAmountHour(value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyRoiAll(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountApplyRoiDay(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountApplyRoiHour(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountOrderCountTotal(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountOrderCountDay(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountOrderCountHour(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountFirstDayOrderCountTotal(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountFirstDayOrderCountDay(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountFirstDayOrderCountHour(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountOrderUserCountTotal(value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderUserCountDay(value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderUserCountHour(value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderRateAll(value2.getOfficialAccountOrderRate());
+            result.setOfficialAccountOrderRateDay(value2.getOfficialAccountOrderRate());
+            result.setOfficialAccountOrderRateHour(value2.getOfficialAccountOrderRate());
+            result.setOfficialAccountOrderCostAll(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderCostDay(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderCostHour(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderAmountTotal(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountOrderAmountDay(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountOrderAmountHour(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountTotal(value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountDay(value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountHour(value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountOrderRoiAll(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountOrderRoiDay(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountOrderRoiHour(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountConsultCountTotal(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountConsultCountDay(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountConsultCountHour(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountReaderCountTotal(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountReaderCountDay(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountReaderCountHour(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountCreditApplyUserCountTotal(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditApplyUserCountDay(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditApplyUserCountHour(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditUserCountTotal(value2.getOfficialAccountCreditUserCount());
+            result.setOfficialAccountCreditUserCountDay(value2.getOfficialAccountCreditUserCount());
+            result.setOfficialAccountCreditUserCountHour(value2.getOfficialAccountCreditUserCount());
+            result.setForwardCountTotal(value2.getForwardCount());
+            result.setForwardCountDay(value2.getForwardCount());
+            result.setForwardCountHour(value2.getForwardCount());
+            result.setForwardUserCountTotal(value2.getForwardUserCount());
+            result.setForwardUserCountDay(value2.getForwardUserCount());
+            result.setForwardUserCountHour(value2.getForwardUserCount());
+            result.setNoInterestCountTotal(value2.getNoInterestCount());
+            result.setNoInterestCountDay(value2.getNoInterestCount());
+            result.setNoInterestCountHour(value2.getNoInterestCount());
+        } else {
+            // 是否是同一天
+            boolean isUnSameDay = !value1.getStatDay().equals(value2.getStatDay());
+            result.setCostDeviationRateTotal(value1.getCostDeviationRateTotal() + value2.getCostDeviationRate());
+            result.setCostDeviationRateDay(isUnSameDay ? 0: value1.getCostDeviationRateDay() + value2.getCostDeviationRate());
+            result.setCostDeviationRateHour(value2.getCostDeviationRate());
+            result.setCostTotal(value1.getCostTotal() + value2.getCost());
+            result.setCostDay(isUnSameDay ? 0: value1.getCostDay() + value2.getCost());
+            result.setCostHour(value2.getCost());
+            result.setCompensationAmountTotal(value1.getCompensationAmountTotal() + value2.getCompensationAmount());
+            result.setCompensationAmountDay(isUnSameDay ? 0: value1.getCompensationAmountDay() + value2.getCompensationAmount());
+            result.setCompensationAmountHour(value2.getCompensationAmount());
+            result.setViewCountTotal(value1.getViewCountTotal() + value2.getViewCount());
+            result.setViewCountDay(isUnSameDay ? 0: value1.getViewCountDay() + value2.getViewCount());
+            result.setViewCountHour(value2.getViewCount());
+            // 总消耗 / 总曝光
+            result.setThousandDisplayPriceAll(result.getViewCountTotal() == 0 ? 0 : (result.getCostTotal() / result.getViewCountTotal() * 1000));
+            result.setThousandDisplayPriceDay(isUnSameDay ? 0: result.getViewCountDay() == 0 ? 0 : (result.getCostDay() / result.getViewCountDay() * 1000));
+            result.setThousandDisplayPriceHour(value2.getThousandDisplayPrice());
+            // 曝光次数 / 曝光人数(拿不到曝光人数)
+            result.setAvgViewPerUserHour(value2.getAvgViewPerUser());
+            result.setValidClickCountTotal(value1.getValidClickCountTotal() + value2.getValidClickCount());
+            result.setValidClickCountDay(isUnSameDay ? 0: value1.getValidClickCountDay() + value2.getValidClickCount());
+            result.setValidClickCountHour(value2.getValidClickCount());
+            // 广告点击次数 / 广告曝光次数
+            result.setCtrAll(result.getViewCountTotal() == 0 ? 0.0 : result.getValidClickCountTotal() / result.getViewCountTotal());
+            result.setCtrDay(isUnSameDay ? 0: result.getViewCountDay() == 0 ? 0.0 : result.getValidClickCountDay() / result.getViewCountDay());
+            result.setCtrHour(value2.getCtr());
+            // 广告花费/广告点击次数
+            result.setCpcAll(result.getValidClickCountTotal() == 0 ? 0 : result.getCostTotal() / result.getValidClickCountTotal());
+            result.setCpcDay(isUnSameDay ? 0: result.getValidClickCountDay() == 0 ? 0 : result.getCostDay() / result.getValidClickCountDay());
+            result.setCpcHour(value2.getCpc());
+            result.setValuableClickCountTotal(value1.getValuableClickCountTotal() + value2.getValuableClickCount());
+            result.setValuableClickCountDay(isUnSameDay ? 0: value1.getValuableClickCountDay() + value2.getValuableClickCount());
+            result.setValuableClickCountHour(value2.getValuableClickCount());
+            // 广告可转化点击次数/广告曝光次数
+            result.setValuableClickRateAll(result.getViewCountTotal() == 0 ? 0.0 : result.getValuableClickCountTotal() / result.getViewCountTotal());
+            result.setValuableClickRateDay(isUnSameDay ? 0: result.getViewCountDay() == 0 ? 0.0 : result.getValuableClickCountDay() / result.getViewCountDay());
+            result.setValuableClickRateHour(value2.getValuableClickRate());
+            // 广告花费/可转化点击次数
+            result.setValuableClickCostAll(result.getValuableClickCountTotal() == 0 ? 0 : result.getCostTotal() / result.getValuableClickCountTotal());
+            result.setValuableClickCostDay(isUnSameDay ? 0: result.getValuableClickCountDay() == 0 ? 0 : result.getCostDay() / result.getValuableClickCountDay());
+            result.setValuableClickCostHour(value2.getValuableClickCost());
+            result.setConversionsCountTotal(value1.getConversionsCountTotal() + value2.getConversionsCount());
+            result.setConversionsCountDay(isUnSameDay ? 0: value1.getConversionsCountDay() + value2.getConversionsCount());
+            result.setConversionsCountHour(value2.getConversionsCount());
+            // 广告花费/转化目标量
+            result.setConversionsCostAll(result.getConversionsCountTotal() == 0 ? 0 : result.getCostTotal() / result.getConversionsCountTotal());
+            result.setConversionsCostDay(isUnSameDay ? 0: result.getConversionsCountDay() == 0 ? 0 : result.getCostDay() / result.getConversionsCountDay());
+            result.setConversionsCostHour(value2.getConversionsCost());
+            // 公众号:转化目标量/点击次数。
+            result.setConversionsRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getConversionsCountTotal() / result.getValidClickCountTotal());
+            result.setConversionsRateDay(isUnSameDay ? 0: result.getValidClickCountDay() == 0 ? 0.0 : result.getConversionsCountDay() / result.getValidClickCountDay());
+            result.setConversionsRateHour(value2.getConversionsRate());
+            result.setDeepConversionsCountTotal(value1.getDeepConversionsCountTotal() + value2.getDeepConversionsCount());
+            result.setDeepConversionsCountDay(isUnSameDay ? 0: value1.getDeepConversionsCountDay() + value2.getDeepConversionsCount());
+            result.setDeepConversionsCountHour(value2.getDeepConversionsCount());
+            // 广告花费/深度转化目标量
+            result.setDeepConversionsCostAll(result.getDeepConversionsCountTotal() == 0 ? 0 : result.getCostTotal() / result.getDeepConversionsCountTotal());
+            result.setDeepConversionsCostDay(isUnSameDay ? 0: result.getDeepConversionsCountDay() == 0 ? 0 : result.getCostDay() / result.getDeepConversionsCountDay());
+            result.setDeepConversionsCostHour(value2.getDeepConversionsCost());
+            // 深度转化目标量/可转化点击次数
+            result.setDeepConversionsRateAll(result.getValuableClickCountTotal() == 0 ? 0.0 : result.getDeepConversionsCountTotal() / result.getValuableClickCountTotal());
+            result.setDeepConversionsRateDay(isUnSameDay ? 0: result.getValuableClickCountDay() == 0 ? 0.0 : result.getDeepConversionsCountDay() / result.getValuableClickCountDay());
+            result.setDeepConversionsRateHour(value2.getDeepConversionsRate());
+            result.setOrderCountTotal(value1.getOrderCountTotal() + value2.getOrderCount());
+            result.setOrderCountDay(isUnSameDay ? 0: value1.getOrderCountDay() + value2.getOrderCount());
+            result.setOrderCountHour(value2.getOrderCount());
+            result.setFirstDayOrderCountTotal(value1.getFirstDayOrderCountTotal() + value2.getFirstDayOrderCount());
+            result.setFirstDayOrderCountDay(isUnSameDay ? 0: value1.getFirstDayOrderCountDay() + value2.getFirstDayOrderCount());
+            result.setFirstDayOrderCountHour(value2.getFirstDayOrderCount());
+            // 广告花费/下单量
+            result.setWebOrderCostAll(result.getOrderCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOrderCountTotal());
+            result.setWebOrderCostDay(isUnSameDay ? 0: result.getOrderCountDay() == 0 ? 0 : result.getCostDay() / result.getOrderCountDay());
+            result.setWebOrderCostHour(value2.getWebOrderCost());
+            // 下单量/点击次数
+            result.setOrderRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getOrderCountTotal() / result.getValidClickCountTotal());
+            result.setOrderRateDay(isUnSameDay ? 0: result.getValidClickCountDay() == 0 ? 0.0 : result.getOrderCountDay() / result.getValidClickCountDay());
+            result.setOrderRateHour(value2.getOrderRate());
+            result.setOrderAmountTotal(value1.getOrderAmountTotal() + value2.getOrderAmount());
+            result.setOrderAmountDay(isUnSameDay ? 0: value1.getOrderAmountDay() + value2.getOrderAmount());
+            result.setOrderAmountHour(value2.getOrderAmount());
+            result.setFirstDayOrderAmountTotal(value1.getFirstDayOrderAmountTotal() + value2.getFirstDayOrderAmount());
+            result.setFirstDayOrderAmountDay(isUnSameDay ? 0: value1.getFirstDayOrderAmountDay() + value2.getFirstDayOrderAmount());
+            result.setFirstDayOrderAmountHour(value2.getFirstDayOrderAmount());
+            // 下单金额/下单量
+            result.setOrderUnitPriceAll(result.getOrderCountTotal() == 0 ? 0 : result.getOrderAmountTotal() / result.getOrderCountTotal());
+            result.setOrderUnitPriceDay(isUnSameDay ? 0: result.getOrderCountDay() == 0 ? 0 : result.getOrderAmountDay() / result.getOrderCountDay());
+            result.setOrderUnitPriceHour(value2.getOrderUnitPrice());
+            // 下单金额/广告花费
+            result.setOrderRoiAll(result.getCostTotal() == 0 ? 0.0 : result.getOrderAmountTotal() / result.getCostTotal());
+            result.setOrderRoiDay(isUnSameDay ? 0: result.getCostDay() == 0 ? 0.0 : result.getOrderAmountDay() / result.getCostDay());
+            result.setOrderRoiHour(value2.getOrderRoi());
+            result.setSignInCountTotal(value1.getSignInCountTotal() + value2.getSignInCount());
+            result.setSignInCountDay(value1.getSignInCountDay() + value2.getSignInCount());
+            result.setSignInCountHour(value2.getSignInCount());
+            result.setScanFollowCountTotal(value1.getScanFollowCountTotal() + value2.getScanFollowCount());
+            result.setScanFollowCountDay(isUnSameDay ? 0: value1.getScanFollowCountDay() + value2.getScanFollowCount());
+            result.setScanFollowCountHour(value2.getScanFollowCount());
+            result.setWechatAppRegisterUvTotal(value1.getWechatAppRegisterUvTotal() + value2.getWechatAppRegisterUv());
+            result.setWechatAppRegisterUvDay(isUnSameDay ? 0: value1.getWechatAppRegisterUvDay() + value2.getWechatAppRegisterUv());
+            result.setWechatAppRegisterUvHour(value2.getWechatAppRegisterUv());
+            // 广告消耗 / 小游戏注册人数
+            result.setWechatMinigameRegisterCostAll(result.getWechatAppRegisterUvTotal() == 0 ? 0 : result.getCostTotal() / result.getWechatAppRegisterUvTotal());
+            result.setWechatMinigameRegisterCostDay(isUnSameDay ? 0: result.getWechatAppRegisterUvDay() == 0 ? 0 : result.getCostDay() / result.getWechatAppRegisterUvDay());
+            result.setWechatMinigameRegisterCostHour(value2.getWechatMinigameRegisterCost());
+            // 小游戏注册人数 / 广告点击次数
+            result.setWechatMinigameRegisterRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getWechatAppRegisterUvTotal() / result.getValidClickCountTotal());
+            result.setWechatMinigameRegisterRateDay(isUnSameDay ? 0: result.getValidClickCountDay() == 0 ? 0.0 : result.getWechatAppRegisterUvDay() / result.getValidClickCountDay());
+            result.setWechatMinigameRegisterRateHour(value2.getWechatMinigameRegisterRate());
+            // 总收益 / 总人数
+            result.setWechatMinigameArpuAll(result.getWechatAppRegisterUvTotal() == 0 ? 0.0 : result.getOrderAmountTotal() / result.getWechatAppRegisterUvTotal());
+            result.setWechatMinigameArpuDay(isUnSameDay ? 0: result.getWechatAppRegisterUvDay() == 0 ? 0.0 : result.getOrderAmountDay() / result.getWechatAppRegisterUvDay());
+            result.setWechatMinigameArpuHour(value2.getWechatMinigameArpu());
+            result.setWechatMinigameRetentionCountTotal(value1.getWechatMinigameRetentionCountTotal() + value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameRetentionCountDay(isUnSameDay ? 0: value1.getWechatMinigameRetentionCountDay() + value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameRetentionCountHour(value2.getWechatMinigameRetentionCount());
+            result.setWechatMinigameCheckoutCountTotal(value1.getWechatMinigameCheckoutCountTotal() + value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutCountDay(isUnSameDay ? 0: value1.getWechatMinigameCheckoutCountDay() + value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutCountHour(value2.getWechatMinigameCheckoutCount());
+            result.setWechatMinigameCheckoutAmountTotal(value1.getWechatMinigameCheckoutAmountTotal() + value2.getWechatMinigameCheckoutAmount());
+            result.setWechatMinigameCheckoutAmountDay(isUnSameDay ? 0: value1.getWechatMinigameCheckoutAmountDay() + value2.getWechatMinigameCheckoutAmount());
+            result.setWechatMinigameCheckoutAmountHour(value2.getWechatMinigameCheckoutAmount());
+            result.setOfficialAccountFollowCountTotal(value1.getOfficialAccountFollowCountTotal() + value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCountDay(isUnSameDay ? 0: value1.getOfficialAccountFollowCountDay() + value2.getOfficialAccountFollowCount());
+            result.setOfficialAccountFollowCountHour(value2.getOfficialAccountFollowCount());
+            // 关注次数 / 点击次数
+            result.setOfficialAccountFollowRateAll(result.getValidClickCountTotal() == 0 ? 0.0 : result.getOfficialAccountFollowCountTotal() / result.getValidClickCountTotal());
+            result.setOfficialAccountFollowRateDay(isUnSameDay ? 0: result.getValidClickCountDay() == 0 ? 0.0 : result.getOfficialAccountFollowCountDay() / result.getValidClickCountDay());
+            result.setOfficialAccountFollowRateHour(value2.getOfficialAccountFollowRate());
+            result.setOfficialAccountRegisterUserCountTotal(value1.getOfficialAccountRegisterUserCountTotal() + value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterUserCountDay(isUnSameDay ? 0: value1.getOfficialAccountRegisterUserCountDay() + value2.getOfficialAccountRegisterUserCount());
+            result.setOfficialAccountRegisterUserCountHour(value2.getOfficialAccountRegisterUserCount());
+            // 公众号内注册人数 / 公众号关注次数
+            result.setOfficialAccountRegisterRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountRegisterUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountRegisterRateDay(isUnSameDay ? 0: result.getOfficialAccountFollowCountDay() == 0 ? 0.0 : result.getOfficialAccountRegisterUserCountDay() / result.getOfficialAccountFollowCountDay());
+            result.setOfficialAccountRegisterRateHour(value2.getOfficialAccountRegisterRate());
+            // 广告消耗 / 广告注册人数
+            result.setOfficialAccountRegisterCostAll(result.getOfficialAccountRegisterUserCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountRegisterUserCountTotal());
+            result.setOfficialAccountRegisterCostDay(isUnSameDay ? 0: result.getOfficialAccountRegisterUserCountDay() == 0 ? 0 : result.getCostDay() / result.getOfficialAccountRegisterUserCountDay());
+            result.setOfficialAccountRegisterCostHour(value2.getOfficialAccountRegisterCost());
+            result.setOfficialAccountRegisterAmountTotal(value1.getOfficialAccountRegisterAmountTotal() + value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterAmountDay(isUnSameDay ? 0: value1.getOfficialAccountRegisterAmountDay() + value2.getOfficialAccountRegisterAmount());
+            result.setOfficialAccountRegisterAmountHour(value2.getOfficialAccountRegisterAmount());
+            // 注册产生的订单金额累计/广告花费
+            result.setOfficialAccountRegisterRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountRegisterAmountTotal() / result.getCostTotal());
+            result.setOfficialAccountRegisterRoiDay(isUnSameDay ? 0: result.getCostDay() == 0 ? 0 : result.getOfficialAccountRegisterAmountDay() / result.getCostDay());
+            result.setOfficialAccountRegisterRoiHour(value2.getOfficialAccountRegisterRoi());
+            result.setOfficialAccountApplyCountTotal(value1.getOfficialAccountApplyCountTotal() + value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyCountDay(isUnSameDay ? 0: value1.getOfficialAccountApplyCountDay() + value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyCountHour(value2.getOfficialAccountApplyCount());
+            result.setOfficialAccountApplyUserCountTotal(value1.getOfficialAccountApplyUserCountTotal() + value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyUserCountDay(isUnSameDay ? 0: value1.getOfficialAccountApplyUserCountDay() + value2.getOfficialAccountApplyUserCount());
+            result.setOfficialAccountApplyUserCountHour(value2.getOfficialAccountApplyUserCount());
+            // 公众号内填单的独立用户数/公众号关注次数
+            result.setOfficialAccountApplyRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountApplyUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountApplyRateDay(isUnSameDay ? 0: result.getOfficialAccountFollowCountDay() == 0 ? 0.0 : result.getOfficialAccountApplyUserCountDay() / result.getOfficialAccountFollowCountDay());
+            result.setOfficialAccountApplyRateHour(value2.getOfficialAccountApplyRate());
+            // 广告花费/广告产生的填单行为数量
+            result.setOfficialAccountApplyCostAll(result.getOfficialAccountApplyUserCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountApplyUserCountTotal());
+            result.setOfficialAccountApplyCostDay(isUnSameDay ? 0: result.getOfficialAccountApplyUserCountDay() == 0 ? 0 : result.getCostDay() / result.getOfficialAccountApplyUserCountDay());
+            result.setOfficialAccountApplyCostHour(value2.getOfficialAccountApplyCost());
+            result.setOfficialAccountApplyAmountTotal(value1.getOfficialAccountApplyAmountTotal() + value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyAmountDay(isUnSameDay ? 0: value1.getOfficialAccountApplyAmountDay() + value2.getOfficialAccountApplyAmount());
+            result.setOfficialAccountApplyAmountHour(value2.getOfficialAccountApplyAmount());
+            // 填单产生的订单金额累计/广告花费
+            result.setOfficialAccountApplyRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountApplyAmountTotal() / result.getCostTotal());
+            result.setOfficialAccountApplyRoiDay(isUnSameDay ? 0: result.getCostDay() == 0 ? 0 : result.getOfficialAccountApplyAmountDay() / result.getCostDay());
+            result.setOfficialAccountApplyRoiHour(value2.getOfficialAccountApplyRoi());
+            result.setOfficialAccountOrderCountTotal(value1.getOfficialAccountOrderCountTotal() + value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountOrderCountDay(isUnSameDay ? 0: value1.getOfficialAccountOrderCountDay() + value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountOrderCountHour(value2.getOfficialAccountOrderCount());
+            result.setOfficialAccountFirstDayOrderCountTotal(value1.getOfficialAccountFirstDayOrderCountTotal() + value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountFirstDayOrderCountDay(isUnSameDay ? 0: value1.getOfficialAccountFirstDayOrderCountDay() + value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountFirstDayOrderCountHour(value2.getOfficialAccountFirstDayOrderCount());
+            result.setOfficialAccountOrderUserCountTotal(value1.getOfficialAccountOrderUserCountTotal() + value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderUserCountDay(isUnSameDay ? 0: value1.getOfficialAccountOrderUserCountDay() + value2.getOfficialAccountOrderUserCount());
+            result.setOfficialAccountOrderUserCountHour(value2.getOfficialAccountOrderUserCount());
+            // 公众号内下单独立用户数(UV)/公众号关注次数
+            result.setOfficialAccountOrderRateAll(result.getOfficialAccountFollowCountTotal() == 0 ? 0.0 : result.getOfficialAccountOrderUserCountTotal() / result.getOfficialAccountFollowCountTotal());
+            result.setOfficialAccountOrderRateDay(isUnSameDay ? 0: result.getOfficialAccountFollowCountDay() == 0 ? 0.0 : result.getOfficialAccountOrderUserCountDay() / result.getOfficialAccountFollowCountDay());
+            result.setOfficialAccountOrderRateHour(value2.getOfficialAccountOrderRate());
+            // 广告花费/广告产生的下单行为数量
+            result.setOfficialAccountOrderCostAll(result.getOfficialAccountOrderCountTotal() == 0 ? 0 : result.getCostTotal() / result.getOfficialAccountOrderCountTotal());
+            result.setOfficialAccountOrderCostDay(isUnSameDay ? 0: result.getOfficialAccountOrderCountDay() == 0 ? 0 : result.getCostDay() / result.getOfficialAccountOrderCountDay());
+            result.setOfficialAccountOrderCostHour(value2.getOfficialAccountOrderCost());
+            result.setOfficialAccountOrderAmountTotal(value1.getOfficialAccountOrderAmountTotal() + value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountOrderAmountDay(isUnSameDay ? 0: value1.getOfficialAccountOrderAmountDay() + value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountOrderAmountHour(value2.getOfficialAccountOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountTotal(value1.getOfficialAccountFirstDayOrderAmountTotal() + value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountDay(isUnSameDay ? 0: value1.getOfficialAccountFirstDayOrderAmountDay() + value2.getOfficialAccountFirstDayOrderAmount());
+            result.setOfficialAccountFirstDayOrderAmountHour(value2.getOfficialAccountFirstDayOrderAmount());
+            // 下单产生的订单金额累计/广告花费
+            result.setOfficialAccountOrderRoiAll(result.getCostTotal() == 0 ? 0 : result.getOfficialAccountOrderAmountTotal() / result.getCostTotal());
+            result.setOfficialAccountOrderRoiDay(isUnSameDay ? 0: result.getCostDay() == 0 ? 0 : result.getOfficialAccountOrderAmountDay() / result.getCostDay());
+            result.setOfficialAccountOrderRoiHour(value2.getOfficialAccountOrderRoi());
+            result.setOfficialAccountConsultCountTotal(value1.getOfficialAccountConsultCountTotal() + value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountConsultCountDay(isUnSameDay ? 0: value1.getOfficialAccountConsultCountDay() + value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountConsultCountHour(value2.getOfficialAccountConsultCount());
+            result.setOfficialAccountReaderCountTotal(value1.getOfficialAccountReaderCountTotal() + value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountReaderCountDay(isUnSameDay ? 0: value1.getOfficialAccountReaderCountDay() + value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountReaderCountHour(value2.getOfficialAccountReaderCount());
+            result.setOfficialAccountCreditApplyUserCountTotal(value1.getOfficialAccountCreditApplyUserCountTotal() + value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditApplyUserCountDay(isUnSameDay ? 0: value1.getOfficialAccountCreditApplyUserCountDay() + value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditApplyUserCountHour(value2.getOfficialAccountCreditApplyUserCount());
+            result.setOfficialAccountCreditUserCountTotal(value1.getOfficialAccountCreditUserCountTotal() + value2.getOfficialAccountCreditUserCount());
+            result.setOfficialAccountCreditUserCountDay(isUnSameDay ? 0: value1.getOfficialAccountCreditUserCountDay() + value2.getOfficialAccountCreditUserCount());
+            result.setOfficialAccountCreditUserCountHour(value2.getOfficialAccountCreditUserCount());
+            result.setForwardCountTotal(value1.getForwardCountTotal() + value2.getForwardCount());
+            result.setForwardCountDay(isUnSameDay ? 0: value1.getForwardCountDay() + value2.getForwardCount());
+            result.setForwardCountHour(value2.getForwardCount());
+            result.setForwardUserCountTotal(value1.getForwardUserCountTotal() + value2.getForwardUserCount());
+            result.setForwardUserCountDay(isUnSameDay ? 0: value1.getForwardUserCountDay() + value2.getForwardUserCount());
+            result.setForwardUserCountHour(value2.getForwardUserCount());
+            result.setNoInterestCountTotal(value1.getNoInterestCountTotal() + value2.getNoInterestCount());
+            result.setNoInterestCountDay(isUnSameDay ? 0: value1.getNoInterestCountDay() + value2.getNoInterestCount());
+            result.setNoInterestCountHour(value2.getNoInterestCount());
+        }
+        return result;
+    }
+
+    public static PlanStatOfHourDWD byMaxCompute(Record record) {
+        PlanStatOfHourDWD result = new PlanStatOfHourDWD();
+        result.setStatDay(ObjectUtil.toString(record.get("stat_day")));
+        result.setHour(ObjectUtil.toInt(record.get("hour")));
+        result.setAccountId(ObjectUtil.toLong(record.get("account_id")));
+        result.setCampaignId(ObjectUtil.toLong(record.get("campaign_id")));
+        result.setAgencyAccountId(ObjectUtil.toLong(record.get("agency_account_id")));
+        result.setWechatAccountId(ObjectUtil.toString(record.get("wechat_account_id")));
+        result.setWechatAgencyId(ObjectUtil.toString(record.get("wechat_agency_id")));
+        result.setAdgroupId(ObjectUtil.toLong(record.get("adgroup_id")));
+        result.setAdId(ObjectUtil.toLong(record.get("ad_id")));
+        result.setCreateTime(ObjectUtil.toDate(record.get("create_time")));
+        result.setCostDeviationRateTotal(ObjectUtil.toDouble(record.get("cost_deviation_rate_total")));
+        result.setCostDeviationRateDay(ObjectUtil.toDouble(record.get("cost_deviation_rate_day")));
+        result.setCostDeviationRateHour(ObjectUtil.toDouble(record.get("cost_deviation_rate_hour")));
+        result.setCostTotal(ObjectUtil.toLong(record.get("cost_total")));
+        result.setCostDay(ObjectUtil.toLong(record.get("cost_day")));
+        result.setCostHour(ObjectUtil.toLong(record.get("cost_hour")));
+        result.setCompensationAmountTotal(ObjectUtil.toLong(record.get("compensation_amount_total")));
+        result.setCompensationAmountDay(ObjectUtil.toLong(record.get("compensation_amount_day")));
+        result.setCompensationAmountHour(ObjectUtil.toLong(record.get("compensation_amount_hour")));
+        result.setViewCountTotal(ObjectUtil.toLong(record.get("view_count_total")));
+        result.setViewCountDay(ObjectUtil.toLong(record.get("view_count_day")));
+        result.setViewCountHour(ObjectUtil.toLong(record.get("view_count_hour")));
+        result.setThousandDisplayPriceAll(ObjectUtil.toLong(record.get("thousand_display_price_all")));
+        result.setThousandDisplayPriceDay(ObjectUtil.toLong(record.get("thousand_display_price_day")));
+        result.setThousandDisplayPriceHour(ObjectUtil.toLong(record.get("thousand_display_price_hour")));
+        result.setAvgViewPerUserHour(ObjectUtil.toDouble(record.get("avg_view_per_user_hour")));
+        result.setValidClickCountTotal(ObjectUtil.toLong(record.get("valid_click_count_total")));
+        result.setValidClickCountDay(ObjectUtil.toLong(record.get("valid_click_count_day")));
+        result.setValidClickCountHour(ObjectUtil.toLong(record.get("valid_click_count_hour")));
+        result.setCtrAll(ObjectUtil.toDouble(record.get("ctr_all")));
+        result.setCtrDay(ObjectUtil.toDouble(record.get("ctr_day")));
+        result.setCtrHour(ObjectUtil.toDouble(record.get("ctr_hour")));
+        result.setCpcAll(ObjectUtil.toLong(record.get("cpc_all")));
+        result.setCpcDay(ObjectUtil.toLong(record.get("cpc_day")));
+        result.setCpcHour(ObjectUtil.toLong(record.get("cpc_hour")));
+        result.setValuableClickCountTotal(ObjectUtil.toLong(record.get("valuable_click_count_total")));
+        result.setValuableClickCountDay(ObjectUtil.toLong(record.get("valuable_click_count_day")));
+        result.setValuableClickCountHour(ObjectUtil.toLong(record.get("valuable_click_count_hour")));
+        result.setValuableClickRateAll(ObjectUtil.toDouble(record.get("valuable_click_rate_all")));
+        result.setValuableClickRateDay(ObjectUtil.toDouble(record.get("valuable_click_rate_day")));
+        result.setValuableClickRateHour(ObjectUtil.toDouble(record.get("valuable_click_rate_hour")));
+        result.setValuableClickCostAll(ObjectUtil.toLong(record.get("valuable_click_cost_all")));
+        result.setValuableClickCostDay(ObjectUtil.toLong(record.get("valuable_click_cost_day")));
+        result.setValuableClickCostHour(ObjectUtil.toLong(record.get("valuable_click_cost_hour")));
+        result.setConversionsCountTotal(ObjectUtil.toLong(record.get("conversions_count_total")));
+        result.setConversionsCountDay(ObjectUtil.toLong(record.get("conversions_count_day")));
+        result.setConversionsCountHour(ObjectUtil.toLong(record.get("conversions_count_hour")));
+        result.setConversionsCostAll(ObjectUtil.toLong(record.get("conversions_cost_all")));
+        result.setConversionsCostDay(ObjectUtil.toLong(record.get("conversions_cost_day")));
+        result.setConversionsCostHour(ObjectUtil.toLong(record.get("conversions_cost_hour")));
+        result.setConversionsRateAll(ObjectUtil.toDouble(record.get("conversions_rate_all")));
+        result.setConversionsRateDay(ObjectUtil.toDouble(record.get("conversions_rate_day")));
+        result.setConversionsRateHour(ObjectUtil.toDouble(record.get("conversions_rate_hour")));
+        result.setDeepConversionsCountTotal(ObjectUtil.toLong(record.get("deep_conversions_count_total")));
+        result.setDeepConversionsCountDay(ObjectUtil.toLong(record.get("deep_conversions_count_day")));
+        result.setDeepConversionsCountHour(ObjectUtil.toLong(record.get("deep_conversions_count_hour")));
+        result.setDeepConversionsCostAll(ObjectUtil.toLong(record.get("deep_conversions_cost_all")));
+        result.setDeepConversionsCostDay(ObjectUtil.toLong(record.get("deep_conversions_cost_day")));
+        result.setDeepConversionsCostHour(ObjectUtil.toLong(record.get("deep_conversions_cost_hour")));
+        result.setDeepConversionsRateAll(ObjectUtil.toDouble(record.get("deep_conversions_rate_all")));
+        result.setDeepConversionsRateDay(ObjectUtil.toDouble(record.get("deep_conversions_rate_day")));
+        result.setDeepConversionsRateHour(ObjectUtil.toDouble(record.get("deep_conversions_rate_hour")));
+        result.setOrderCountTotal(ObjectUtil.toLong(record.get("order_count_total")));
+        result.setOrderCountDay(ObjectUtil.toLong(record.get("order_count_day")));
+        result.setOrderCountHour(ObjectUtil.toLong(record.get("order_count_hour")));
+        result.setFirstDayOrderCountTotal(ObjectUtil.toLong(record.get("first_day_order_count_total")));
+        result.setFirstDayOrderCountDay(ObjectUtil.toLong(record.get("first_day_order_count_day")));
+        result.setFirstDayOrderCountHour(ObjectUtil.toLong(record.get("first_day_order_count_hour")));
+        result.setWebOrderCostAll(ObjectUtil.toLong(record.get("web_order_cost_all")));
+        result.setWebOrderCostDay(ObjectUtil.toLong(record.get("web_order_cost_day")));
+        result.setWebOrderCostHour(ObjectUtil.toLong(record.get("web_order_cost_hour")));
+        result.setOrderRateAll(ObjectUtil.toDouble(record.get("order_rate_all")));
+        result.setOrderRateDay(ObjectUtil.toDouble(record.get("order_rate_day")));
+        result.setOrderRateHour(ObjectUtil.toDouble(record.get("order_rate_hour")));
+        result.setOrderAmountTotal(ObjectUtil.toLong(record.get("order_amount_total")));
+        result.setOrderAmountDay(ObjectUtil.toLong(record.get("order_amount_day")));
+        result.setOrderAmountHour(ObjectUtil.toLong(record.get("order_amount_hour")));
+        result.setFirstDayOrderAmountTotal(ObjectUtil.toLong(record.get("first_day_order_amount_total")));
+        result.setFirstDayOrderAmountDay(ObjectUtil.toLong(record.get("first_day_order_amount_day")));
+        result.setFirstDayOrderAmountHour(ObjectUtil.toLong(record.get("first_day_order_amount_hour")));
+        result.setOrderUnitPriceAll(ObjectUtil.toLong(record.get("order_unit_price_all")));
+        result.setOrderUnitPriceDay(ObjectUtil.toLong(record.get("order_unit_price_day")));
+        result.setOrderUnitPriceHour(ObjectUtil.toLong(record.get("order_unit_price_hour")));
+        result.setOrderRoiAll(ObjectUtil.toDouble(record.get("order_roi_all")));
+        result.setOrderRoiDay(ObjectUtil.toDouble(record.get("order_roi_day")));
+        result.setOrderRoiHour(ObjectUtil.toDouble(record.get("order_roi_hour")));
+        result.setSignInCountTotal(ObjectUtil.toLong(record.get("sign_in_count_total")));
+        result.setSignInCountDay(ObjectUtil.toLong(record.get("sign_in_count_day")));
+        result.setSignInCountHour(ObjectUtil.toLong(record.get("sign_in_count_hour")));
+        result.setScanFollowCountTotal(ObjectUtil.toLong(record.get("scan_follow_count_total")));
+        result.setScanFollowCountDay(ObjectUtil.toLong(record.get("scan_follow_count_day")));
+        result.setScanFollowCountHour(ObjectUtil.toLong(record.get("scan_follow_count_hour")));
+        result.setWechatAppRegisterUvTotal(ObjectUtil.toLong(record.get("wechat_app_register_uv_total")));
+        result.setWechatAppRegisterUvDay(ObjectUtil.toLong(record.get("wechat_app_register_uv_day")));
+        result.setWechatAppRegisterUvHour(ObjectUtil.toLong(record.get("wechat_app_register_uv_hour")));
+        result.setWechatMinigameRegisterCostAll(ObjectUtil.toLong(record.get("wechat_minigame_register_cost_all")));
+        result.setWechatMinigameRegisterCostDay(ObjectUtil.toLong(record.get("wechat_minigame_register_cost_day")));
+        result.setWechatMinigameRegisterCostHour(ObjectUtil.toLong(record.get("wechat_minigame_register_cost_hour")));
+        result.setWechatMinigameRegisterRateAll(ObjectUtil.toDouble(record.get("wechat_minigame_register_rate_all")));
+        result.setWechatMinigameRegisterRateDay(ObjectUtil.toDouble(record.get("wechat_minigame_register_rate_day")));
+        result.setWechatMinigameRegisterRateHour(ObjectUtil.toDouble(record.get("wechat_minigame_register_rate_hour")));
+        result.setWechatMinigameArpuAll(ObjectUtil.toDouble(record.get("wechat_minigame_arpu_all")));
+        result.setWechatMinigameArpuDay(ObjectUtil.toDouble(record.get("wechat_minigame_arpu_day")));
+        result.setWechatMinigameArpuHour(ObjectUtil.toDouble(record.get("wechat_minigame_arpu_hour")));
+        result.setWechatMinigameRetentionCountTotal(ObjectUtil.toLong(record.get("wechat_minigame_retention_count_total")));
+        result.setWechatMinigameRetentionCountDay(ObjectUtil.toLong(record.get("wechat_minigame_retention_count_day")));
+        result.setWechatMinigameRetentionCountHour(ObjectUtil.toLong(record.get("wechat_minigame_retention_count_hour")));
+        result.setWechatMinigameCheckoutCountTotal(ObjectUtil.toLong(record.get("wechat_minigame_checkout_count_total")));
+        result.setWechatMinigameCheckoutCountDay(ObjectUtil.toLong(record.get("wechat_minigame_checkout_count_day")));
+        result.setWechatMinigameCheckoutCountHour(ObjectUtil.toLong(record.get("wechat_minigame_checkout_count_hour")));
+        result.setWechatMinigameCheckoutAmountTotal(ObjectUtil.toLong(record.get("wechat_minigame_checkout_amount_total")));
+        result.setWechatMinigameCheckoutAmountDay(ObjectUtil.toLong(record.get("wechat_minigame_checkout_amount_day")));
+        result.setWechatMinigameCheckoutAmountHour(ObjectUtil.toLong(record.get("wechat_minigame_checkout_amount_hour")));
+        result.setOfficialAccountFollowCountTotal(ObjectUtil.toLong(record.get("official_account_follow_count_total")));
+        result.setOfficialAccountFollowCountDay(ObjectUtil.toLong(record.get("official_account_follow_count_day")));
+        result.setOfficialAccountFollowCountHour(ObjectUtil.toLong(record.get("official_account_follow_count_hour")));
+        result.setOfficialAccountFollowRateAll(ObjectUtil.toDouble(record.get("official_account_follow_rate_all")));
+        result.setOfficialAccountFollowRateDay(ObjectUtil.toDouble(record.get("official_account_follow_rate_day")));
+        result.setOfficialAccountFollowRateHour(ObjectUtil.toDouble(record.get("official_account_follow_rate_hour")));
+        result.setOfficialAccountRegisterUserCountTotal(ObjectUtil.toLong(record.get("official_account_register_user_count_total")));
+        result.setOfficialAccountRegisterUserCountDay(ObjectUtil.toLong(record.get("official_account_register_user_count_day")));
+        result.setOfficialAccountRegisterUserCountHour(ObjectUtil.toLong(record.get("official_account_register_user_count_hour")));
+        result.setOfficialAccountRegisterRateAll(ObjectUtil.toDouble(record.get("official_account_register_rate_all")));
+        result.setOfficialAccountRegisterRateDay(ObjectUtil.toDouble(record.get("official_account_register_rate_day")));
+        result.setOfficialAccountRegisterRateHour(ObjectUtil.toDouble(record.get("official_account_register_rate_hour")));
+        result.setOfficialAccountRegisterCostAll(ObjectUtil.toLong(record.get("official_account_register_cost_all")));
+        result.setOfficialAccountRegisterCostDay(ObjectUtil.toLong(record.get("official_account_register_cost_day")));
+        result.setOfficialAccountRegisterCostHour(ObjectUtil.toLong(record.get("official_account_register_cost_hour")));
+        result.setOfficialAccountRegisterAmountTotal(ObjectUtil.toLong(record.get("official_account_register_amount_total")));
+        result.setOfficialAccountRegisterAmountDay(ObjectUtil.toLong(record.get("official_account_register_amount_day")));
+        result.setOfficialAccountRegisterAmountHour(ObjectUtil.toLong(record.get("official_account_register_amount_hour")));
+        result.setOfficialAccountRegisterRoiAll(ObjectUtil.toLong(record.get("official_account_register_roi_all")));
+        result.setOfficialAccountRegisterRoiDay(ObjectUtil.toLong(record.get("official_account_register_roi_day")));
+        result.setOfficialAccountRegisterRoiHour(ObjectUtil.toLong(record.get("official_account_register_roi_hour")));
+        result.setOfficialAccountApplyCountTotal(ObjectUtil.toLong(record.get("official_account_apply_count_total")));
+        result.setOfficialAccountApplyCountDay(ObjectUtil.toLong(record.get("official_account_apply_count_day")));
+        result.setOfficialAccountApplyCountHour(ObjectUtil.toLong(record.get("official_account_apply_count_hour")));
+        result.setOfficialAccountApplyUserCountTotal(ObjectUtil.toLong(record.get("official_account_apply_user_count_total")));
+        result.setOfficialAccountApplyUserCountDay(ObjectUtil.toLong(record.get("official_account_apply_user_count_day")));
+        result.setOfficialAccountApplyUserCountHour(ObjectUtil.toLong(record.get("official_account_apply_user_count_hour")));
+        result.setOfficialAccountApplyRateAll(ObjectUtil.toDouble(record.get("official_account_apply_rate_all")));
+        result.setOfficialAccountApplyRateDay(ObjectUtil.toDouble(record.get("official_account_apply_rate_day")));
+        result.setOfficialAccountApplyRateHour(ObjectUtil.toDouble(record.get("official_account_apply_rate_hour")));
+        result.setOfficialAccountApplyCostAll(ObjectUtil.toLong(record.get("official_account_apply_cost_all")));
+        result.setOfficialAccountApplyCostDay(ObjectUtil.toLong(record.get("official_account_apply_cost_day")));
+        result.setOfficialAccountApplyCostHour(ObjectUtil.toLong(record.get("official_account_apply_cost_hour")));
+        result.setOfficialAccountApplyAmountTotal(ObjectUtil.toLong(record.get("official_account_apply_amount_total")));
+        result.setOfficialAccountApplyAmountDay(ObjectUtil.toLong(record.get("official_account_apply_amount_day")));
+        result.setOfficialAccountApplyAmountHour(ObjectUtil.toLong(record.get("official_account_apply_amount_hour")));
+        result.setOfficialAccountApplyRoiAll(ObjectUtil.toLong(record.get("official_account_apply_roi_all")));
+        result.setOfficialAccountApplyRoiDay(ObjectUtil.toLong(record.get("official_account_apply_roi_day")));
+        result.setOfficialAccountApplyRoiHour(ObjectUtil.toLong(record.get("official_account_apply_roi_hour")));
+        result.setOfficialAccountOrderCountTotal(ObjectUtil.toLong(record.get("official_account_order_count_total")));
+        result.setOfficialAccountOrderCountDay(ObjectUtil.toLong(record.get("official_account_order_count_day")));
+        result.setOfficialAccountOrderCountHour(ObjectUtil.toLong(record.get("official_account_order_count_hour")));
+        result.setOfficialAccountFirstDayOrderCountTotal(ObjectUtil.toLong(record.get("official_account_first_day_order_count_total")));
+        result.setOfficialAccountFirstDayOrderCountDay(ObjectUtil.toLong(record.get("official_account_first_day_order_count_day")));
+        result.setOfficialAccountFirstDayOrderCountHour(ObjectUtil.toLong(record.get("official_account_first_day_order_count_hour")));
+        result.setOfficialAccountOrderUserCountTotal(ObjectUtil.toLong(record.get("official_account_order_user_count_total")));
+        result.setOfficialAccountOrderUserCountDay(ObjectUtil.toLong(record.get("official_account_order_user_count_day")));
+        result.setOfficialAccountOrderUserCountHour(ObjectUtil.toLong(record.get("official_account_order_user_count_hour")));
+        result.setOfficialAccountOrderRateAll(ObjectUtil.toDouble(record.get("official_account_order_rate_all")));
+        result.setOfficialAccountOrderRateDay(ObjectUtil.toDouble(record.get("official_account_order_rate_day")));
+        result.setOfficialAccountOrderRateHour(ObjectUtil.toDouble(record.get("official_account_order_rate_hour")));
+        result.setOfficialAccountOrderCostAll(ObjectUtil.toLong(record.get("official_account_order_cost_all")));
+        result.setOfficialAccountOrderCostDay(ObjectUtil.toLong(record.get("official_account_order_cost_day")));
+        result.setOfficialAccountOrderCostHour(ObjectUtil.toLong(record.get("official_account_order_cost_hour")));
+        result.setOfficialAccountOrderAmountTotal(ObjectUtil.toLong(record.get("official_account_order_amount_total")));
+        result.setOfficialAccountOrderAmountDay(ObjectUtil.toLong(record.get("official_account_order_amount_day")));
+        result.setOfficialAccountOrderAmountHour(ObjectUtil.toLong(record.get("official_account_order_amount_hour")));
+        result.setOfficialAccountFirstDayOrderAmountTotal(ObjectUtil.toLong(record.get("official_account_first_day_order_amount_total")));
+        result.setOfficialAccountFirstDayOrderAmountDay(ObjectUtil.toLong(record.get("official_account_first_day_order_amount_day")));
+        result.setOfficialAccountFirstDayOrderAmountHour(ObjectUtil.toLong(record.get("official_account_first_day_order_amount_hour")));
+        result.setOfficialAccountOrderRoiAll(ObjectUtil.toLong(record.get("official_account_order_roi_all")));
+        result.setOfficialAccountOrderRoiDay(ObjectUtil.toLong(record.get("official_account_order_roi_day")));
+        result.setOfficialAccountOrderRoiHour(ObjectUtil.toLong(record.get("official_account_order_roi_hour")));
+        result.setOfficialAccountConsultCountTotal(ObjectUtil.toLong(record.get("official_account_consult_count_total")));
+        result.setOfficialAccountConsultCountDay(ObjectUtil.toLong(record.get("official_account_consult_count_day")));
+        result.setOfficialAccountConsultCountHour(ObjectUtil.toLong(record.get("official_account_consult_count_hour")));
+        result.setOfficialAccountReaderCountTotal(ObjectUtil.toLong(record.get("official_account_reader_count_total")));
+        result.setOfficialAccountReaderCountDay(ObjectUtil.toLong(record.get("official_account_reader_count_day")));
+        result.setOfficialAccountReaderCountHour(ObjectUtil.toLong(record.get("official_account_reader_count_hour")));
+        result.setOfficialAccountCreditApplyUserCountTotal(ObjectUtil.toLong(record.get("official_account_credit_apply_user_count_total")));
+        result.setOfficialAccountCreditApplyUserCountDay(ObjectUtil.toLong(record.get("official_account_credit_apply_user_count_day")));
+        result.setOfficialAccountCreditApplyUserCountHour(ObjectUtil.toLong(record.get("official_account_credit_apply_user_count_hour")));
+        result.setOfficialAccountCreditUserCountTotal(ObjectUtil.toLong(record.get("official_account_credit_user_count_total")));
+        result.setOfficialAccountCreditUserCountDay(ObjectUtil.toLong(record.get("official_account_credit_user_count_day")));
+        result.setOfficialAccountCreditUserCountHour(ObjectUtil.toLong(record.get("official_account_credit_user_count_hour")));
+        result.setForwardCountTotal(ObjectUtil.toLong(record.get("forward_count_total")));
+        result.setForwardCountDay(ObjectUtil.toLong(record.get("forward_count_day")));
+        result.setForwardCountHour(ObjectUtil.toLong(record.get("forward_count_hour")));
+        result.setForwardUserCountTotal(ObjectUtil.toLong(record.get("forward_user_count_total")));
+        result.setForwardUserCountDay(ObjectUtil.toLong(record.get("forward_user_count_day")));
+        result.setForwardUserCountHour(ObjectUtil.toLong(record.get("forward_user_count_hour")));
+        result.setNoInterestCountTotal(ObjectUtil.toLong(record.get("no_interest_count_total")));
+        result.setNoInterestCountDay(ObjectUtil.toLong(record.get("no_interest_count_day")));
+        result.setNoInterestCountHour(ObjectUtil.toLong(record.get("no_interest_count_hour")));
+        return result;
+    }
+}

+ 10 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/util/DateUtil.java

@@ -11,6 +11,8 @@ public class DateUtil {
     public static final DateTimeFormatter FORMAT_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
     public static final DateTimeFormatter FORMAT_TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
 
+    public static final DateTimeFormatter FORMAT_MINUTE_REDUCE = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH:mm");
+
     public static String formatLocalDate(LocalDate date) {
         return date.format(FORMAT_DATE);
     }
@@ -19,6 +21,14 @@ public class DateUtil {
         return dateTime.format(FORMAT_DATETIME);
     }
 
+    public static String formatOfMinuteReduce(LocalDateTime dateTime) {
+        return dateTime.format(FORMAT_MINUTE_REDUCE);
+    }
+
+    public static LocalDateTime parseOfMinuteReduce(String reduceTime) {
+        return LocalDateTime.parse(reduceTime, FORMAT_MINUTE_REDUCE);
+    }
+
     public static LocalDate parseLocalDate(String dateStr) {
         return LocalDate.parse(dateStr, FORMAT_DATE);
     }

+ 48 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/util/PlanUtil.java

@@ -0,0 +1,48 @@
+package flink.zanxiangnet.ad.monitoring.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class PlanUtil {
+    public static Set<Long> parseAdStr(String adIdsStr) {
+        if (StringUtils.isBlank(adIdsStr)) {
+            return new HashSet<>(3);
+        }
+        return Arrays.stream(adIdsStr.split(",")).map(Long::valueOf).collect(Collectors.toSet());
+    }
+
+    public static Map<Long, List<Long>> parseAdGroupMapStr(String adGroupMapStr) {
+        if (StringUtils.isBlank(adGroupMapStr)) {
+            return new HashMap<>(2);
+        }
+        Map<Long, List> mapTemp = JsonUtil.toMap(adGroupMapStr, Map.class, Long.class, List.class);
+        Map<Long, List<Long>> adGroupMap = new HashMap<>(mapTemp.size());
+        mapTemp.forEach((key, value) -> {
+            List<Long> temp = new ArrayList<>(value.size());
+            value.forEach(adId -> temp.add(ObjectUtil.toLong(adId)));
+            adGroupMap.put(key, temp);
+        });
+        return adGroupMap;
+    }
+
+    public static String adIdsStr(Set<Long> adIds) {
+        if (CollectionUtils.isEmpty(adIds)) {
+            return null;
+        }
+        return StringUtils.join(adIds, ",");
+    }
+
+    public static String adIdsStr(Long adId) {
+        return String.valueOf(adId);
+    }
+
+    public static String adGroupMapStr(Map<Long, List<Long>> adGroupIds) {
+        if (adGroupIds == null || adGroupIds.isEmpty()) {
+            return null;
+        }
+        return JsonUtil.toString(adGroupIds);
+    }
+}

+ 2 - 2
flink-ad-monitoring/src/main/resources/ad_stream_of_day.properties

@@ -1,8 +1,8 @@
 kafka.servers=114.55.59.94:9093,112.124.33.132:9093
 kafka.username=alikafka_pre-cn-tl32fsx4l00x
 kafka.password=VOEdhZLjOrL76lrl5bqPtydtoEkbs0Ny
-#kafka.sslPath=D:\\Downloads\\kafka.client.truststore.jks
-kafka.sslPath=/root/flink-1.13.2/kafka.client.truststore.jks
+kafka.sslPath=D:\\Downloads\\kafka.client.truststore.jks
+# kafka.sslPath=/root/flink-1.13.2/kafka.client.truststore.jks
 kafka.topic=ad_day_cost_topic
 kafka.groupId=ad_day_cost_group
 

+ 2 - 2
flink-ad-monitoring/src/main/resources/ad_stream_of_minute.properties

@@ -1,8 +1,8 @@
 kafka.servers=114.55.59.94:9093,112.124.33.132:9093
 kafka.username=alikafka_pre-cn-tl32fsx4l00x
 kafka.password=VOEdhZLjOrL76lrl5bqPtydtoEkbs0Ny
-#kafka.sslPath=D:\\Downloads\\kafka.client.truststore.jks
-kafka.sslPath=/root/flink-1.13.2/kafka.client.truststore.jks
+kafka.sslPath=D:\\Downloads\\kafka.client.truststore.jks
+#kafka.sslPath=/root/flink-1.13.2/kafka.client.truststore.jks
 kafka.topic=ad_cost_topic
 kafka.groupId=ad_cost_group
 

+ 9 - 9
flink-ad-monitoring/src/main/resources/application.properties

@@ -1,10 +1,10 @@
-#maxCompute.accountId=LTAI5tFuLw65UsH3tqru2K1h
-#maxCompute.accountKey=p1F8my4ovgcEfs3HVORdmeLlLUUKRp
-#maxCompute.endpoint=http://service.cn-hangzhou.maxcompute.aliyun.com/api
-#maxCompute.projectName=zx_ad_monitoring
-#maxCompute.tunnelEndpoint=http://dt.cn-hangzhou.maxcompute.aliyun.com
-maxCompute.accountId=LTAI5tF8Vfwm8hVajbKewiDZ
-maxCompute.accountKey=rjOgeffIRMV7r5T6LBsOC47GI60Xge
+maxCompute.accountId=LTAI5tFuLw65UsH3tqru2K1h
+maxCompute.accountKey=p1F8my4ovgcEfs3HVORdmeLlLUUKRp
 maxCompute.endpoint=http://service.cn-hangzhou.maxcompute.aliyun.com/api
-maxCompute.projectName=zx_test02
-maxCompute.tunnelEndpoint=http://dt.cn-hangzhou.maxcompute.aliyun.com
+maxCompute.projectName=zx_ad_monitoring
+maxCompute.tunnelEndpoint=http://dt.cn-hangzhou.maxcompute.aliyun.com
+#maxCompute.accountId=LTAI5tF8Vfwm8hVajbKewiDZ
+#maxCompute.accountKey=rjOgeffIRMV7r5T6LBsOC47GI60Xge
+#maxCompute.endpoint=http://service.cn-hangzhou.maxcompute.aliyun.com/api
+#maxCompute.projectName=zx_test02
+#maxCompute.tunnelEndpoint=http://dt.cn-hangzhou.maxcompute.aliyun.com