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

完成 ods的写入

wcc 3 éve
szülő
commit
415d415ccd
18 módosított fájl, 2189 hozzáadás és 1498 törlés
  1. 1 1
      flink-ad-monitoring/pom.xml
  2. 38 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/KafkaBatchJob.java
  3. 217 46
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/KafkaDemoJob.java
  4. 178 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/Test.java
  5. 0 15
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/AdGroupInfo.java
  6. 0 64
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/AdInfo.java
  7. 0 39
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/PlanInfo.java
  8. 0 1324
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/StatInfo.java
  9. 20 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/dto/AdStatOfDayDWDDTO.java
  10. 21 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/dto/AdStatOfDayODSDTO.java
  11. 470 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdDataOfHourODS.java
  12. 7 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdDataOfMinuteODS.java
  13. 1033 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfDayDWD.java
  14. 159 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdStatOfHourDWD.java
  15. 19 0
      flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/util/DateUtil.java
  16. 9 3
      flink-ad-monitoring/src/main/resources/ad_stream_of_day.properties
  17. 9 3
      flink-ad-monitoring/src/main/resources/ad_stream_of_minute.properties
  18. 8 3
      flink-ad-monitoring/src/main/resources/application.properties

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

@@ -30,7 +30,7 @@ under the License.
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <flink.version>1.13.0</flink.version>
+        <flink.version>1.14.0</flink.version>
         <target.java.version>1.8</target.java.version>
         <scala.binary.version>2.11</scala.binary.version>
         <maven.compiler.source>${target.java.version}</maven.compiler.source>

+ 38 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/KafkaBatchJob.java

@@ -0,0 +1,38 @@
+package flink.zanxiangnet.ad.monitoring;
+
+import org.apache.flink.api.java.ExecutionEnvironment;
+
+/**
+ * 看起来有点鸡肋
+ */
+public class KafkaBatchJob {
+    public static void main(String[] args) throws Exception {
+        final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+
+        /*
+         * Here, you can start creating your execution plan for Flink.
+         *
+         * Start with getting some data from the environment, like
+         * 	env.readTextFile(textPath);
+         *
+         * then, transform the resulting DataSet<String> using operations
+         * like
+         * 	.filter()
+         * 	.flatMap()
+         * 	.join()
+         * 	.coGroup()
+         *
+         * and many more.
+         * Have a look at the programming guide for the Java API:
+         *
+         * https://flink.apache.org/docs/latest/apis/batch/index.html
+         *
+         * and the examples
+         *
+         * https://flink.apache.org/docs/latest/apis/batch/examples.html
+         *
+         */
+
+        env.execute("Flink Batch Java API Skeleton");
+    }
+}

+ 217 - 46
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/KafkaDemoJob.java

@@ -1,42 +1,63 @@
 package flink.zanxiangnet.ad.monitoring;
 
+import com.aliyun.odps.Odps;
+import com.aliyun.odps.account.Account;
+import com.aliyun.odps.account.AliyunAccount;
 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.maxcompute.sink.TunnelStreamSink;
 import flink.zanxiangnet.ad.monitoring.pojo.dto.AdDataOfDayDTO;
-import flink.zanxiangnet.ad.monitoring.pojo.entity.AdDataOfDayODS;
+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;
 import flink.zanxiangnet.ad.monitoring.pojo.properties.KafkaProperties;
 import flink.zanxiangnet.ad.monitoring.pojo.dto.AdDataOfMinuteDTO;
-import flink.zanxiangnet.ad.monitoring.pojo.entity.AdDataOfMinuteODS;
 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.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.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;
+import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
+import org.apache.flink.streaming.api.windowing.time.Time;
+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.Date;
+import java.util.Map;
 import java.util.Properties;
 
 public class KafkaDemoJob {
 
     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();
 
@@ -56,33 +77,119 @@ public class KafkaDemoJob {
 
         DataStreamSource<String> adStreamOfMinuteIn = env.fromSource(adStreamOfMinuteSource, WatermarkStrategy.noWatermarks(), "adStreamOfMinuteSource_kafka");
 
-        SingleOutputStreamOperator<AdDataOfMinuteODS> adMinuteOdsStream = adStreamOfMinuteIn.filter(StringUtils::isNotBlank)
-                .map(str -> {
-                    AdDataOfMinuteDTO dto = JsonUtil.toObj(str, AdDataOfMinuteDTO.class);
-                    LocalDateTime statTime = DateUtil.milliToLocalDateTime(dto.getCreateTime());
-                    HourlyReportsGetListStruct struct = dto.getHourlyReportsGetListStruct();
-                    AdDataOfMinuteODS adOds = new AdDataOfMinuteODS();
-                    BeanUtils.copyProperties(struct, adOds);
-                    adOds.setStatDay(DateUtil.formatLocalDate(statTime.toLocalDate()));
-                    adOds.setHour(dto.getHourlyReportsGetListStruct().getHour().intValue());
-                    adOds.setStatTime(dto.getCreateTime());
-                    adOds.setAccountId(dto.getAccountId());
-                    adOds.setAgencyAccountId(dto.getHourlyReportsGetListStruct().getAccountId());
-                    return adOds;
-                })
-                // 打水印,延迟 12分钟,同时指定时间流
-                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfMinuteODS>forBoundedOutOfOrderness(Duration.ofMinutes(12L))
+        // 广告分钟数据(前 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 = dto.getDataTime() == null ? createTime : dto.getDataTime();
+                        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);
+                        } 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);
+                        }
+                    }
+                });
+
+        // 分钟流
+        SingleOutputStreamOperator<AdDataOfMinuteODS> adMinuteOdsStream = adOdsStream.getSideOutput(adMinuteStreamTag)
+                // 打水印,允许延迟 60分钟,同时指定时间流
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfMinuteODS>forBoundedOutOfOrderness(Duration.ofMinutes(60L))
                         .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfMinuteODS>) (adOds, l) -> adOds.getStatTime())
                 );
+        // 写入原始表
         adMinuteOdsStream.addSink(new TunnelBatchSink<>(AdDataOfMinuteODS.class, 36000L, 64000L, 3));
 
+        // 小时流(直接写到小时报表的 ods)
+        SingleOutputStreamOperator<AdDataOfHourODS> adHourOdsStream = adOdsStream.getSideOutput(adHourStreamTag)
+                // 打水印,允许延迟 10天(应为允许回滚 10天),同时指定事件时间
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfHourODS>forBoundedOutOfOrderness(Duration.ofDays(10L))
+                        .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfHourODS>) (adOds, l) -> adOds.getStatTime())
+                );
+        // 写入原始表
+        adHourOdsStream.addSink(new TunnelBatchSink<>(AdDataOfHourODS.class, 36000L, 64000L, 10));
+
+        // 获取指定广告的历史统计信息(用于统计总的消耗信息等)
+        /*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(KafkaDemoJob.class.getResourceAsStream("/ad_stream_of_day.properties"));
         KafkaSource<String> adStreamOfDaySource = buildKafkaSource(adStreamOfDayProps);
 
         DataStreamSource<String> adStreamOfDayIn = env.fromSource(adStreamOfDaySource, WatermarkStrategy.noWatermarks(), "adStreamOfMinuteSource_kafka");
 
-        SingleOutputStreamOperator<AdDataOfDayODS> adDayOdsStream = adStreamOfDayIn.filter(StringUtils::isNotBlank)
+        // 广告日数据。往前回滚 10天
+        final OutputTag<AdDataOfDayODS> adDayStreamRollDayTag = new OutputTag<AdDataOfDayODS>("adDayStreamRollDayTag") {
+        };
+        // 广告日数据。往前回滚 1年
+        final OutputTag<AdStatOfDayDWDDTO> adDayStreamRollYearTag = new OutputTag<AdStatOfDayDWDDTO>("adDayStreamRollYearTag") {
+        };
+        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayOdsStream = adStreamOfDayIn.filter(StringUtils::isNotBlank)
                 .map(str -> {
                     AdDataOfDayDTO dto = JsonUtil.toObj(str, AdDataOfDayDTO.class);
                     Date createTime = new Date(dto.getCreateTime());
@@ -97,33 +204,48 @@ public class KafkaDemoJob {
                     adOds.setAdgroupId(struct.getAdgroupId());
                     adOds.setAdId(struct.getAdId());
                     adOds.setCreateTime(createTime);
-                    return adOds;
+                    return AdStatOfDayODSDTO.builder()
+                            .startDate(dto.getStartDate())
+                            .endDate(dto.getEndDate())
+                            .adDataOfDayODS(adOds)
+                            .build();
                 });
-        adDayOdsStream.addSink(new TunnelBatchSink<>(AdDataOfDayODS.class, 36000L, 6000L, 200));
+        adDayOdsStream.map(AdStatOfDayODSDTO::getAdDataOfDayODS).addSink(new TunnelBatchSink<>(AdDataOfDayODS.class, 36000L, 6000L, 10));
 
-        // 获取指定广告的历史统计信息(用于统计总的消耗信息等)
-        /*SingleOutputStreamOperator<AdStatOfHourDWD> oldAdStream = adOdsStream.map(new RichMapFunction<AdDataOfMinuteODS, AdStatOfHourDWD>() {
-            // 在这里初始化 MaxCompute连接实例
-            private Odps odps;
+        // 拆分流
+        SingleOutputStreamOperator<AdStatOfDayODSDTO> adDayOdsStreamSplit = adDayOdsStream.process(new ProcessFunction<AdStatOfDayODSDTO, AdStatOfDayODSDTO>() {
             @Override
-            public void open(Configuration parameters) throws Exception {
-                Account account = new AliyunAccount("LTAI5tFuLw65UsH3tqru2K1h", "p1F8my4ovgcEfs3HVORdmeLlLUUKRp");
-                odps = new Odps(account);
-                // odps.setEndpoint("http://service.odps.aliyun.com/api");
-                odps.setEndpoint("http://service.cn-hangzhou.maxcompute.aliyun.com/api");
-                // http://dt.cn-hangzhou.maxcompute.aliyun.com
-                odps.setDefaultProject("zx_ad_monitoring");
-            }
-            @Override
-            public AdStatOfHourDWD map(AdDataOfMinuteODS adDataOfMinuteODS) throws Exception {
-                Instance i = SQLTask.run(odps, "SELECT * FROM ");
-                i.waitForSuccess();
-                for(Record record : SQLTask.getResult(i)) {
-                    record.get(0);
+            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, AdStatOfDayDWDDTO.builder()
+                            .startDate(startDate)
+                            .endDate(endDate)
+                            .adStatOfDayDWD(AdStatOfDayDWD.byOds(adOds))
+                            .build());
+                } else {
+                    // 每日往前回滚 10天的数据
+                    context.output(adDayStreamRollDayTag, adOds);
                 }
-                return null;
             }
-        });*/
+        });
+
+        SingleOutputStreamOperator<AdDataOfDayODS> adDayOdsOfDayStream = adDayOdsStreamSplit.getSideOutput(adDayStreamRollDayTag)
+                // 打水印,允许延迟 10天(应为允许回滚 10天),同时指定事件时间
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdDataOfDayODS>forBoundedOutOfOrderness(Duration.ofDays(10L))
+                        .withTimestampAssigner((SerializableTimestampAssigner<AdDataOfDayODS>) (adDay, l) -> DateUtil.localDateToMilli(DateUtil.parseLocalDate(adDay.getStatDay())))
+                );
+
+        /*SingleOutputStreamOperator<AdStatOfDayDWDDTO> adDayOdsOfYearStream = adDayOdsStreamSplit.getSideOutput(adDayStreamRollYearTag)
+                // 打水印,允许延迟 365天(应为允许回滚 365天),同时指定事件时间
+                .assignTimestampsAndWatermarks(WatermarkStrategy.<AdStatOfDayDWDDTO>forBoundedOutOfOrderness(Duration.ofDays(366L))
+                        .withTimestampAssigner((SerializableTimestampAssigner<AdStatOfDayDWDDTO>) (dto, l) -> DateUtil.localDateToMilli(DateUtil.parseLocalDate(dto.getAdStatOfDayDWD().getStatDay()))))
+                .keyBy((KeySelector<AdStatOfDayDWD, String>) adStatOfDayDWD -> adStatOfDayDWD.getStatDay() + "_" + adStatOfDayDWD.getAdId())
+                // 开一个以天为单位的窗口
+                .window(TumblingEventTimeWindows.of(Time.days(1L), Time.hours(-8)));*/
 
         /*adOdsStream.join(oldAdStream)
                 .where((KeySelector<AdDataOfMinuteODS, Long>) AdDataOfMinuteODS::getAdId)
@@ -276,6 +398,53 @@ public class KafkaDemoJob {
         );
     }
 
+    /**
+     * 内网
+     *
+     * @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 + "\";");
@@ -284,6 +453,8 @@ public class KafkaDemoJob {
         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)

+ 178 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/Test.java

@@ -0,0 +1,178 @@
+package flink.zanxiangnet.ad.monitoring;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import flink.zanxiangnet.ad.monitoring.util.DateUtil;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
+import org.apache.flink.api.common.eventtime.WatermarkStrategy;
+import org.apache.flink.api.common.functions.AggregateFunction;
+import org.apache.flink.api.java.tuple.Tuple5;
+import org.apache.flink.configuration.Configuration;
+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.source.RichSourceFunction;
+import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
+import org.apache.flink.streaming.api.windowing.time.Time;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class Test {
+    public static void main(String[] args) throws Exception {
+        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
+
+        DataStreamSource<Pojo> source = env.addSource(new PojoSource());
+        // 打水印,延迟 2秒,同时指定时间流
+        SingleOutputStreamOperator<Pojo> pojoStream = source.assignTimestampsAndWatermarks(WatermarkStrategy.<Pojo>forBoundedOutOfOrderness(Duration.ofHours(2))
+                .withTimestampAssigner((SerializableTimestampAssigner<Pojo>) (pojo, l) -> pojo.getCreateTime())
+        );
+        pojoStream.keyBy(Pojo::getUserId)
+                .window(TumblingEventTimeWindows.of(Time.days(1L), Time.hours(-8)))
+                .aggregate(new AggregateFunction<Pojo, Tuple5<Integer, Long, Long, Integer, List<Long>>, String>() {
+
+                    @Override
+                    public Tuple5<Integer, Long, Long, Integer, List<Long>> createAccumulator() {
+                        return new Tuple5<>(0, Long.MAX_VALUE, 0L, 0, new ArrayList<>());
+                    }
+
+                    @Override
+                    public Tuple5<Integer, Long, Long, Integer, List<Long>> add(Pojo pojo, Tuple5<Integer, Long, Long, Integer, List<Long>> tuple5) {
+                        tuple5.f4.add(pojo.getIndex());
+                        return new Tuple5<>(pojo.getUserId(), Math.min(pojo.getCreateTime(), tuple5.f1), Math.max(pojo.getCreateTime(), tuple5.f2), tuple5.f3 + 1, tuple5.f4);
+                    }
+
+                    @Override
+                    public String getResult(Tuple5<Integer, Long, Long, Integer, List<Long>> tuple5) {
+                        return tuple5.f0 + "-" + DateUtil.formatLocalDateTime(DateUtil.milliToLocalDateTime(tuple5.f1)) + " : " + DateUtil.formatLocalDateTime(DateUtil.milliToLocalDateTime(tuple5.f2)) + " : " + tuple5.f3 + " : " + tuple5.f4;
+                    }
+
+                    @Override
+                    public Tuple5<Integer, Long, Long, Integer, List<Long>> merge(Tuple5<Integer, Long, Long, Integer, List<Long>> tuple5, Tuple5<Integer, Long, Long, Integer, List<Long>> acc) {
+                        List<Long> temp = new ArrayList<>(tuple5.f4);
+                        temp.addAll(acc.f4);
+                        return new Tuple5<>(tuple5.f0, Math.min(acc.f1, tuple5.f1), Math.max(acc.f2, tuple5.f2), tuple5.f3 + acc.f3, temp);
+                    }
+                }).print();
+
+        env.execute();
+    }
+
+    /**
+     * 模拟从 2021-01-01开始,每小时打一次卡
+     */
+    public static class PojoSource extends RichSourceFunction<Pojo> {
+        // 2021-01-01 00:00:00
+        private static final long BEGIN = 1609430400000L;
+
+        // 对象锁,防止MaxCompute的 Tunnel对象多次初始化
+        private static final Object DUMMY_LOCK = new Object();
+
+        private static AtomicLong index1;
+        private static AtomicLong index2;
+        private boolean isRun = false;
+        private static ThreadPoolExecutor threadPool;
+
+        @Override
+        public void open(Configuration configuration) {
+            isRun = true;
+            if (index1 == null) {
+                synchronized (DUMMY_LOCK) {
+                    if (index1 == null) {
+                        index1 = new AtomicLong(12);
+                        index2 = new AtomicLong(0);
+                        threadPool = new ThreadPoolExecutor(
+                                60,
+                                60,
+                                0L,
+                                TimeUnit.MILLISECONDS,
+                                new LinkedBlockingQueue<>(),
+                                new ThreadFactoryBuilder()
+                                        .setNameFormat("maxcompute-writer-%d").build());
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void run(SourceContext<Pojo> sourceContext) {
+            while (isRun) {
+                try {
+                    long user1 = index1.incrementAndGet();
+                    Pojo pojo = Pojo.builder()
+                            .userId(1)
+                            .index(user1)
+                            .createTime(BEGIN + ((user1 - 1) * 60 * 60 * 1000))
+                            .build();
+                    if (user1 % 24 == 0) {
+                        // 模拟数据延迟,每天 24点的数据延迟 25秒
+                        threadPool.execute(() -> {
+                            try {
+                                Thread.sleep(25);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                            System.out.println("延迟1发送: " + pojo);
+                            sourceContext.collect(pojo);
+                        });
+                    } else {
+                        System.out.println("1发送: " + pojo);
+                        sourceContext.collect(pojo);
+                    }
+                    long user2 = index2.incrementAndGet();
+                    Pojo pojo2 = Pojo.builder()
+                            .userId(2)
+                            .index(user2)
+                            .createTime(BEGIN + ((user2 - 1) * 60 * 60 * 1000))
+                            .build();
+                    if (user2 % 24 == 0) {
+                        // 模拟数据延迟,每天 24点的数据延迟 25秒
+                        threadPool.execute(() -> {
+                            try {
+                                Thread.sleep(25);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                            System.out.println("延迟2发送: " + pojo2);
+                            sourceContext.collect(pojo2);
+                        });
+                    } else {
+                        System.out.println("2发送: " + pojo2);
+                        sourceContext.collect(pojo2);
+                    }
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        @Override
+        public void cancel() {
+            isRun = false;
+        }
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @Builder
+    public static class Pojo {
+        private int userId;
+        private long index;
+        private long createTime;
+
+        @Override
+        public String toString() {
+            return "{\"userId\":" + userId + ",\"index\":" + index + ",\"createTime\":" + DateUtil.formatLocalDateTime(DateUtil.milliToLocalDateTime(createTime)) + "}";
+        }
+    }
+}

+ 0 - 15
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/AdGroupInfo.java

@@ -1,15 +0,0 @@
-package flink.zanxiangnet.ad.monitoring.pojo;
-
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class AdGroupInfo {
-    /**
-     * 广告组 id
-     */
-    private Long adgroupId;
-
-    private List<AdInfo> adList;
-}

+ 0 - 64
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/AdInfo.java

@@ -1,64 +0,0 @@
-package flink.zanxiangnet.ad.monitoring.pojo;
-
-import lombok.Data;
-
-import java.time.LocalDate;
-
-@Data
-public class AdInfo {
-
-    /**
-     * 统计时间
-     */
-    private Long statTime;
-
-    /**
-     * 统计的日期
-     */
-    private LocalDate statDay;
-
-    /**
-     * 统计的小时
-     */
-    private Integer hour;
-
-    /**
-     * 腾讯广告应用的账号 id
-     */
-    private Long accountId;
-
-    /**
-     * 计划 id
-     */
-    private Long campaignId;
-
-    /**
-     * 服务商账号 id
-     */
-    private Long agencyAccountId;
-
-    /**
-     * 微信账号id
-     */
-    private String wechatAccountId;
-
-    /**
-     * 微信服务商id
-     */
-    private String wechatAgencyId;
-
-    /**
-     * 广告组 id
-     */
-    private Long adgroupId;
-
-    /**
-     * 广告 id
-     */
-    private Long adId;
-
-    /**
-     * 统计信息
-     */
-    private StatInfo statInfo;
-}

+ 0 - 39
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/PlanInfo.java

@@ -1,39 +0,0 @@
-package flink.zanxiangnet.ad.monitoring.pojo;
-import lombok.Data;
-
-import java.time.LocalDate;
-import java.util.List;
-
-@Data
-public class PlanInfo {
-
-    /**
-     * 统计时间
-     */
-    private Long statTime;
-
-    /**
-     * 统计的日期
-     */
-    private LocalDate statDay;
-
-    /**
-     * 统计的小时
-     */
-    private Integer hour;
-
-    /**
-     * 腾讯广告应用的账号 id
-     */
-    private Long accountId;
-
-    /**
-     * 计划 id
-     */
-    private Long campaignId;
-
-    /**
-     * 计划中的广告组
-     */
-    private List<AdGroupInfo> adGroupList;
-}

+ 0 - 1324
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/StatInfo.java

@@ -1,1324 +0,0 @@
-package flink.zanxiangnet.ad.monitoring.pojo;
-
-import com.google.gson.annotations.SerializedName;
-import lombok.Data;
-
-@Data
-public class StatInfo {
-    @SerializedName("cost_deviation_rate")
-    private Double costDeviationRate;
-
-    @SerializedName("cost")
-    private Long cost;
-
-    @SerializedName("compensation_amount")
-    private Long compensationAmount;
-
-    @SerializedName("view_count")
-    private Long viewCount;
-
-    @SerializedName("thousand_display_price")
-    private Long thousandDisplayPrice;
-
-    @SerializedName("avg_view_per_user")
-    private Double avgViewPerUser;
-
-    @SerializedName("special_page_exp_uv")
-    private Long specialPageExpUv;
-
-    @SerializedName("special_page_exp_cost")
-    private Long specialPageExpCost;
-
-    @SerializedName("valid_click_count")
-    private Long validClickCount;
-
-    @SerializedName("ctr")
-    private Double ctr;
-
-    @SerializedName("cpc")
-    private Long cpc;
-
-    @SerializedName("valuable_click_count")
-    private Long valuableClickCount;
-
-    @SerializedName("valuable_click_rate")
-    private Double valuableClickRate;
-
-    @SerializedName("valuable_click_cost")
-    private Long valuableClickCost;
-
-    @SerializedName("click_image_count")
-    private Long clickImageCount;
-
-    @SerializedName("image_click_user_count")
-    private Long imageClickUserCount;
-
-    @SerializedName("video_play_count")
-    private Long videoPlayCount;
-
-    @SerializedName("video_click_user_count")
-    private Long videoClickUserCount;
-
-    @SerializedName("click_detail_count")
-    private Long clickDetailCount;
-
-    @SerializedName("link_click_user_count")
-    private Long linkClickUserCount;
-
-    @SerializedName("click_head_count")
-    private Long clickHeadCount;
-
-    @SerializedName("portrait_click_user_count")
-    private Long portraitClickUserCount;
-
-    @SerializedName("click_nick_count")
-    private Long clickNickCount;
-
-
-
-
-    @SerializedName("download_count")
-    private Long downloadCount;
-
-    @SerializedName("activated_count")
-    private Long activatedCount;
-
-    @SerializedName("activated_rate")
-    private Double activatedRate;
-
-    @SerializedName("key_page_view_cost")
-    private Long keyPageViewCost;
-
-    @SerializedName("coupon_click_count")
-    private Long couponClickCount;
-
-    @SerializedName("coupon_issue_count")
-    private Long couponIssueCount;
-
-    @SerializedName("coupon_get_count")
-    private Long couponGetCount;
-
-    @SerializedName("platform_page_view_count")
-    private Long platformPageViewCount;
-
-    @SerializedName("platform_page_view_rate")
-    private Double platformPageViewRate;
-
-    @SerializedName("web_commodity_page_view_count")
-    private Long webCommodityPageViewCount;
-
-    @SerializedName("web_commodity_page_view_cost")
-    private Long webCommodityPageViewCost;
-
-    @SerializedName("web_register_count")
-    private Long webRegisterCount;
-
-    @SerializedName("page_consult_count")
-    private Long pageConsultCount;
-
-    @SerializedName("page_consult_cost")
-    private Long pageConsultCost;
-
-    @SerializedName("page_phone_call_direct_count")
-    private Long pagePhoneCallDirectCount;
-
-    @SerializedName("page_phone_call_direct_cost")
-    private Long pagePhoneCallDirectCost;
-
-    @SerializedName("page_phone_call_back_count")
-    private Long pagePhoneCallBackCount;
-
-    @SerializedName("page_phone_call_back_cost")
-    private Long pagePhoneCallBackCost;
-
-    @SerializedName("own_page_navigation_count")
-    private Long ownPageNavigationCount;
-
-    @SerializedName("own_page_navi_cost")
-    private Long ownPageNaviCost;
-
-    @SerializedName("platform_page_navigation_count")
-    private Long platformPageNavigationCount;
-
-    @SerializedName("platform_page_navigation_cost")
-    private Long platformPageNavigationCost;
-
-    @SerializedName("platform_shop_navigation_count")
-    private Long platformShopNavigationCount;
-
-    @SerializedName("platform_shop_navigation_cost")
-    private Long platformShopNavigationCost;
-
-    @SerializedName("web_application_count")
-    private Long webApplicationCount;
-
-    @SerializedName("web_application_cost")
-    private Long webApplicationCost;
-
-    @SerializedName("page_reservation_count")
-    private Long pageReservationCount;
-
-    @SerializedName("page_reservation_rate")
-    private Double pageReservationRate;
-
-    @SerializedName("page_reservation_cost")
-    private Long pageReservationCost;
-
-    @SerializedName("page_reservation_cost_with_people")
-    private Long pageReservationCostWithPeople;
-
-    @SerializedName("add_to_cart_price")
-    private Long addToCartPrice;
-
-    @SerializedName("own_page_coupon_get_count")
-    private Long ownPageCouponGetCount;
-
-    @SerializedName("own_page_coupon_get_cost")
-    private Long ownPageCouponGetCost;
-
-    @SerializedName("platform_coupon_get_count")
-    private Long platformCouponGetCount;
-
-    @SerializedName("platform_coupon_get_cost")
-    private Long platformCouponGetCost;
-
-    @SerializedName("web_order_count")
-    private Long webOrderCount;
-
-    @SerializedName("web_order_rate")
-    private Double webOrderRate;
-
-    @SerializedName("app_order_rate")
-    private Double appOrderRate;
-
-    @SerializedName("web_order_cost")
-    private Long webOrderCost;
-
-    @SerializedName("web_checkout_amount")
-    private Long webCheckoutAmount;
-
-    @SerializedName("web_checkout_count")
-    private Long webCheckoutCount;
-
-    @SerializedName("web_checkout_cost")
-    private Long webCheckoutCost;
-
-    @SerializedName("order_amount")
-    private Long orderAmount;
-
-    @SerializedName("order_unit_price")
-    private Long orderUnitPrice;
-
-    @SerializedName("order_roi")
-    private Double orderRoi;
-
-    @SerializedName("deliver_count")
-    private Long deliverCount;
-
-    @SerializedName("deliver_cost")
-    private Long deliverCost;
-
-    @SerializedName("sign_in_count")
-    private Long signInCount;
-
-    @SerializedName("sign_in_cost")
-    private Long signInCost;
-
-    @SerializedName("download_rate")
-    private Double downloadRate;
-
-    @SerializedName("download_cost")
-    private Long downloadCost;
-
-    @SerializedName("install_count")
-    private Long installCount;
-
-    @SerializedName("install_cost")
-    private Long installCost;
-
-    @SerializedName("click_activated_rate")
-    private Double clickActivatedRate;
-
-    @SerializedName("activated_cost")
-    private Long activatedCost;
-
-    @SerializedName("retention_count")
-    private Long retentionCount;
-
-    @SerializedName("retention_rate")
-    private Double retentionRate;
-
-    @SerializedName("app_key_page_retention_rate")
-    private Double appKeyPageRetentionRate;
-
-    @SerializedName("retention_cost")
-    private Long retentionCost;
-
-    @SerializedName("key_page_view_count")
-    private Long keyPageViewCount;
-
-    @SerializedName("app_commodity_page_view_count")
-    private Long appCommodityPageViewCount;
-
-    @SerializedName("app_commodity_page_view_rate")
-    private Double appCommodityPageViewRate;
-
-    @SerializedName("web_commodity_page_view_rate")
-    private Double webCommodityPageViewRate;
-
-    @SerializedName("app_commodity_page_view_cost")
-    private Long appCommodityPageViewCost;
-
-    @SerializedName("app_register_count")
-    private Long appRegisterCount;
-
-    @SerializedName("app_register_cost")
-    private Long appRegisterCost;
-
-    @SerializedName("web_register_cost")
-    private Long webRegisterCost;
-
-    @SerializedName("app_application_count")
-    private Long appApplicationCount;
-
-    @SerializedName("app_application_cost")
-    private Long appApplicationCost;
-
-    @SerializedName("app_add_to_cart_count")
-    private Long appAddToCartCount;
-
-    @SerializedName("add_to_cart_amount")
-    private Long addToCartAmount;
-
-    @SerializedName("app_add_to_cart_cost")
-    private Long appAddToCartCost;
-
-    @SerializedName("app_order_count")
-    private Long appOrderCount;
-
-    @SerializedName("app_order_cost")
-    private Long appOrderCost;
-
-    @SerializedName("app_checkout_count")
-    private Long appCheckoutCount;
-
-    @SerializedName("app_checkout_amount")
-    private Long appCheckoutAmount;
-
-    @SerializedName("app_checkout_cost")
-    private Long appCheckoutCost;
-
-    @SerializedName("platform_coupon_click_count")
-    private Long platformCouponClickCount;
-
-    @SerializedName("platform_coupon_get_rate")
-    private Double platformCouponGetRate;
-
-    @SerializedName("coupon_usage_number")
-    private Long couponUsageNumber;
-
-    @SerializedName("coupon_usage_cost")
-    private Long couponUsageCost;
-
-    @SerializedName("coupon_usage_rate")
-    private Double couponUsageRate;
-
-    @SerializedName("coupon_purchase_rate")
-    private Double couponPurchaseRate;
-
-    @SerializedName("follow_count")
-    private Long followCount;
-
-    @SerializedName("follow_cost")
-    private Long followCost;
-
-    @SerializedName("forward_count")
-    private Long forwardCount;
-
-    @SerializedName("forward_cost")
-    private Long forwardCost;
-
-    @SerializedName("read_count")
-    private Long readCount;
-
-    @SerializedName("read_cost")
-    private Long readCost;
-
-    @SerializedName("praise_count")
-    private Long praiseCount;
-
-    @SerializedName("praise_cost")
-    private Long praiseCost;
-
-    @SerializedName("comment_count")
-    private Long commentCount;
-
-    @SerializedName("comment_cost")
-    private Long commentCost;
-
-    @SerializedName("inte_phone_count")
-    private Long intePhoneCount;
-
-    @SerializedName("phone_call_count")
-    private Long phoneCallCount;
-
-    @SerializedName("external_form_reservation_count")
-    private Long externalFormReservationCount;
-
-    @SerializedName("app_ad_paying_users")
-    private Long appAdPayingUsers;
-
-    @SerializedName("ad_pur_val_web")
-    private Long adPurValWeb;
-
-    @SerializedName("ad_pur_val_app")
-    private Long adPurValApp;
-
-    @SerializedName("order_24h_count")
-    private Long order24hCount;
-
-    @SerializedName("order_24h_rate")
-    private Double order24hRate;
-
-    @SerializedName("order_24h_cost")
-    private Long order24hCost;
-
-    @SerializedName("order_24h_amount")
-    private Long order24hAmount;
-
-    @SerializedName("order_24h_roi")
-    private Double order24hRoi;
-
-    @SerializedName("game_create_role_count")
-    private Long gameCreateRoleCount;
-
-    @SerializedName("game_authorize_count")
-    private Long gameAuthorizeCount;
-
-    @SerializedName("game_tutorial_finish_count")
-    private Long gameTutorialFinishCount;
-
-    @SerializedName("effective_leads_count")
-    private Long effectiveLeadsCount;
-
-    @SerializedName("effective_cost")
-    private Long effectiveCost;
-
-    @SerializedName("effective_reserve_count")
-    private Long effectiveReserveCount;
-
-    @SerializedName("effective_consult_count")
-    private Long effectiveConsultCount;
-
-    @SerializedName("effective_phone_count")
-    private Long effectivePhoneCount;
-
-    @SerializedName("potential_reserve_count")
-    private Long potentialReserveCount;
-
-    @SerializedName("potential_consult_count")
-    private Long potentialConsultCount;
-
-    @SerializedName("potential_phone_count")
-    private Long potentialPhoneCount;
-
-    @SerializedName("app_checkout_rate")
-    private Double appCheckoutRate;
-
-    @SerializedName("web_checkout_rate")
-    private Double webCheckoutRate;
-
-    @SerializedName("app_activated_checkout_rate")
-    private Double appActivatedCheckoutRate;
-
-    @SerializedName("web_activated_checkout_rate")
-    private Double webActivatedCheckoutRate;
-
-    @SerializedName("app_register_rate")
-    private Double appRegisterRate;
-
-    @SerializedName("web_reg_rate")
-    private Double webRegRate;
-
-    @SerializedName("page_phone_call_direct_rate")
-    private Double pagePhoneCallDirectRate;
-
-    @SerializedName("page_phone_call_back_rate")
-    private Double pagePhoneCallBackRate;
-
-    @SerializedName("page_consult_rate")
-    private Double pageConsultRate;
-
-    @SerializedName("deliver_rate")
-    private Double deliverRate;
-
-    @SerializedName("install_rate")
-    private Double installRate;
-
-    @SerializedName("arppu_cost")
-    private Long arppuCost;
-
-    @SerializedName("arpu_cost")
-    private Long arpuCost;
-
-    @SerializedName("web_arppu_cost")
-    private Long webArppuCost;
-
-    @SerializedName("web_arpu_cost")
-    private Long webArpuCost;
-
-    @SerializedName("app_ad_pur_arpu_cost")
-    private Long appAdPurArpuCost;
-
-    @SerializedName("app_ad_pur_arppu_cost")
-    private Long appAdPurArppuCost;
-
-    @SerializedName("web_ad_pur_arpu_cost")
-    private Long webAdPurArpuCost;
-
-    @SerializedName("cheout_fd")
-    private Long cheoutFd;
-
-    @SerializedName("cheout_td")
-    private Long cheoutTd;
-
-    @SerializedName("cheout_ow")
-    private Long cheoutOw;
-
-    @SerializedName("cheout_tw")
-    private Long cheoutTw;
-
-    @SerializedName("cheout_om")
-    private Long cheoutOm;
-
-    @SerializedName("cheout_fd_reward")
-    private Double cheoutFdReward;
-
-    @SerializedName("cheout_td_reward")
-    private Double cheoutTdReward;
-
-    @SerializedName("cheout_ow_reward")
-    private Double cheoutOwReward;
-
-    @SerializedName("cheout_tw_reward")
-    private Double cheoutTwReward;
-
-    @SerializedName("cheout_om_reward")
-    private Double cheoutOmReward;
-
-    @SerializedName("cheout_total_reward")
-    private Double cheoutTotalReward;
-
-    @SerializedName("from_follow_uv")
-    private Long fromFollowUv;
-
-    @SerializedName("from_follow_cost")
-    private Long fromFollowCost;
-
-    @SerializedName("add_desktop_pv")
-    private Long addDesktopPv;
-
-    @SerializedName("add_desktop_cost")
-    private Long addDesktopCost;
-
-    @SerializedName("first_pay_count")
-    private Long firstPayCount;
-
-    @SerializedName("first_pay_rate")
-    private Double firstPayRate;
-
-    @SerializedName("pre_cre_web")
-    private Long preCreWeb;
-
-    @SerializedName("pre_cre_app")
-    private Long preCreApp;
-
-    @SerializedName("pre_cre_web_val")
-    private Long preCreWebVal;
-
-    @SerializedName("pre_cre_app_val")
-    private Long preCreAppVal;
-
-    @SerializedName("cre_web")
-    private Long creWeb;
-
-    @SerializedName("cre_app")
-    private Long creApp;
-
-    @SerializedName("cre_web_val")
-    private Long creWebVal;
-
-    @SerializedName("cre_app_val")
-    private Long creAppVal;
-
-    @SerializedName("withdr_dep_web")
-    private Long withdrDepWeb;
-
-    @SerializedName("withdr_dep_app")
-    private Long withdrDepApp;
-
-    @SerializedName("withdr_dep_web_val")
-    private Long withdrDepWebVal;
-
-    @SerializedName("withdr_dep_app_val")
-    private Long withdrDepAppVal;
-
-    @SerializedName("first_pay_cost")
-    private Long firstPayCost;
-
-    @SerializedName("landing_page_click_count")
-    private Long landingPageClickCount;
-
-    @SerializedName("web_cart_amount")
-    private Long webCartAmount;
-
-    @SerializedName("scan_follow_count")
-    private Long scanFollowCount;
-
-    @SerializedName("scan_follow_user_count")
-    private Long scanFollowUserCount;
-
-    @SerializedName("scan_follow_user_cost")
-    private Long scanFollowUserCost;
-
-    @SerializedName("scan_follow_user_rate")
-    private Double scanFollowUserRate;
-
-    @SerializedName("app_order_amount")
-    private Long appOrderAmount;
-
-    @SerializedName("web_order_amount")
-    private Long webOrderAmount;
-
-    @SerializedName("phone_consult_count")
-    private Long phoneConsultCount;
-
-    @SerializedName("tool_consult_count")
-    private Long toolConsultCount;
-
-    @SerializedName("lottery_leads_count")
-    private Long lotteryLeadsCount;
-
-    @SerializedName("lottery_leads_cost")
-    private Long lotteryLeadsCost;
-
-    @SerializedName("conversions_count")
-    private Long conversionsCount;
-
-    @SerializedName("conversions_rate")
-    private Double conversionsRate;
-
-    @SerializedName("conversions_cost")
-    private Long conversionsCost;
-
-    @SerializedName("deep_conversions_count")
-    private Long deepConversionsCount;
-
-    @SerializedName("deep_conversions_rate")
-    private Double deepConversionsRate;
-
-    @SerializedName("deep_conversions_cost")
-    private Long deepConversionsCost;
-
-    @SerializedName("first_memcard_web_count")
-    private Long firstMemcardWebCount;
-
-    @SerializedName("first_memcard_app_count")
-    private Long firstMemcardAppCount;
-
-    @SerializedName("memcard_web_count")
-    private Long memcardWebCount;
-
-    @SerializedName("memcard_app_count")
-    private Long memcardAppCount;
-
-    @SerializedName("first_memcard_web_rate")
-    private Double firstMemcardWebRate;
-
-    @SerializedName("first_memcard_app_rate")
-    private Double firstMemcardAppRate;
-
-    @SerializedName("first_memcard_web_cost")
-    private Long firstMemcardWebCost;
-
-    @SerializedName("first_memcard_app_cost")
-    private Long firstMemcardAppCost;
-
-    @SerializedName("click_poi_count")
-    private Long clickPoiCount;
-
-    @SerializedName("video_inner_play_count")
-    private Long videoInnerPlayCount;
-
-    @SerializedName("lan_button_click_count")
-    private Long lanButtonClickCount;
-
-    @SerializedName("lan_jump_button_clickers")
-    private Long lanJumpButtonClickers;
-
-    @SerializedName("lan_jump_button_click_cost")
-    private Long lanJumpButtonClickCost;
-
-    @SerializedName("lan_jump_button_ctr")
-    private Double lanJumpButtonCtr;
-
-    @SerializedName("lan_button_click_cost")
-    private Long lanButtonClickCost;
-
-    @SerializedName("cpn_click_button_count")
-    private Long cpnClickButtonCount;
-
-    @SerializedName("cpn_click_button_uv")
-    private Long cpnClickButtonUv;
-
-    @SerializedName("key_page_uv")
-    private Long keyPageUv;
-
-    @SerializedName("view_commodity_page_uv")
-    private Long viewCommodityPageUv;
-
-    @SerializedName("effect_leads_purchase_count")
-    private Long effectLeadsPurchaseCount;
-
-    @SerializedName("reservation_uv")
-    private Long reservationUv;
-
-    @SerializedName("overall_leads_purchase_count")
-    private Long overallLeadsPurchaseCount;
-
-    @SerializedName("leads_purchase_count")
-    private Long leadsPurchaseCount;
-
-    @SerializedName("leads_purchase_rate")
-    private Double leadsPurchaseRate;
-
-    @SerializedName("leads_purchase_cost")
-    private Long leadsPurchaseCost;
-
-    @SerializedName("leads_purchase_uv")
-    private Long leadsPurchaseUv;
-
-    @SerializedName("valid_leads_uv")
-    private Long validLeadsUv;
-
-    @SerializedName("phone_call_uv")
-    private Long phoneCallUv;
-
-    @SerializedName("valid_phone_uv")
-    private Long validPhoneUv;
-
-    @SerializedName("potential_customer_phone_uv")
-    private Long potentialCustomerPhoneUv;
-
-    @SerializedName("web_register_uv")
-    private Long webRegisterUv;
-
-    @SerializedName("web_apply_uv")
-    private Long webApplyUv;
-
-    @SerializedName("web_credit_uv")
-    private Long webCreditUv;
-
-    @SerializedName("app_apply_uv")
-    private Long appApplyUv;
-
-    @SerializedName("app_pre_credit_uv")
-    private Long appPreCreditUv;
-
-    @SerializedName("app_credit_uv")
-    private Long appCreditUv;
-
-    @SerializedName("app_withdraw_uv")
-    private Long appWithdrawUv;
-
-    @SerializedName("wechat_app_register_uv")
-    private Long wechatAppRegisterUv;
-
-    @SerializedName("no_interest_count")
-    private Long noInterestCount;
-
-    @SerializedName("first_day_order_count")
-    private Long firstDayOrderCount;
-
-    @SerializedName("first_day_order_amount")
-    private Long firstDayOrderAmount;
-
-    @SerializedName("add_wishlist_count")
-    private Long addWishlistCount;
-
-    @SerializedName("video_outer_play10_count")
-    private Long videoOuterPlay10Count;
-
-    @SerializedName("video_outer_play25_count")
-    private Long videoOuterPlay25Count;
-
-    @SerializedName("video_outer_play50_count")
-    private Long videoOuterPlay50Count;
-
-    @SerializedName("video_outer_play75_count")
-    private Long videoOuterPlay75Count;
-
-    @SerializedName("video_outer_play95_count")
-    private Long videoOuterPlay95Count;
-
-    @SerializedName("video_outer_play100_count")
-    private Long videoOuterPlay100Count;
-
-    @SerializedName("video_outer_play_time_count")
-    private Double videoOuterPlayTimeCount;
-
-    @SerializedName("video_outer_play_time_avg_rate")
-    private Double videoOuterPlayTimeAvgRate;
-
-    @SerializedName("video_outer_play_rate")
-    private Double videoOuterPlayRate;
-
-    @SerializedName("video_outer_play_cost")
-    private Long videoOuterPlayCost;
-
-    @SerializedName("video_outer_play_count")
-    private Long videoOuterPlayCount;
-
-    @SerializedName("video_outer_play3s_count")
-    private Long videoOuterPlay3sCount;
-
-    @SerializedName("video_outer_play5s_count")
-    private Long videoOuterPlay5sCount;
-
-    @SerializedName("video_outer_play7s_count")
-    private Long videoOuterPlay7sCount;
-
-    @SerializedName("effect_leads_purchase_cost")
-    private Long effectLeadsPurchaseCost;
-
-    @SerializedName("cre_web_cost")
-    private Long creWebCost;
-
-    @SerializedName("cre_app_cost")
-    private Long creAppCost;
-
-    @SerializedName("pre_cre_web_cost")
-    private Long preCreWebCost;
-
-    @SerializedName("pre_cre_app_cost")
-    private Long preCreAppCost;
-
-    @SerializedName("store_visitor")
-    private Long storeVisitor;
-
-    @SerializedName("try_out_user")
-    private Long tryOutUser;
-
-    @SerializedName("consult_leave_info_users")
-    private Long consultLeaveInfoUsers;
-
-    @SerializedName("active_page_views")
-    private Long activePageViews;
-
-    @SerializedName("active_page_viewers")
-    private Long activePageViewers;
-
-    @SerializedName("active_page_interaction_amount")
-    private Long activePageInteractionAmount;
-
-    @SerializedName("active_page_interaction_users")
-    private Long activePageInteractionUsers;
-
-    @SerializedName("join_chat_group_amount")
-    private Long joinChatGroupAmount;
-
-    @SerializedName("join_chat_group_number_of_people")
-    private Long joinChatGroupNumberOfPeople;
-
-    @SerializedName("join_chat_group_cost_by_people")
-    private Long joinChatGroupCostByPeople;
-
-    @SerializedName("guide_to_follow_page_views")
-    private Long guideToFollowPageViews;
-
-    @SerializedName("guide_to_follow_page_viewers")
-    private Long guideToFollowPageViewers;
-
-    @SerializedName("guide_to_follow_page_interaction_amount")
-    private Long guideToFollowPageInteractionAmount;
-
-    @SerializedName("guide_to_follow_page_interaction_users")
-    private Long guideToFollowPageInteractionUsers;
-
-    @SerializedName("mini_game_register_users")
-    private Long miniGameRegisterUsers;
-
-    @SerializedName("mini_game_register_cost")
-    private Long miniGameRegisterCost;
-
-    @SerializedName("mini_game_register_rate")
-    private Double miniGameRegisterRate;
-
-    @SerializedName("mini_game_ad_monetization_users")
-    private Long miniGameAdMonetizationUsers;
-
-    @SerializedName("mini_game_paying_count")
-    private Long miniGamePayingCount;
-
-    @SerializedName("mini_game_paying_amount")
-    private Long miniGamePayingAmount;
-
-    @SerializedName("mini_game_first_paying_users")
-    private Long miniGameFirstPayingUsers;
-
-    @SerializedName("mini_game_create_role_users")
-    private Long miniGameCreateRoleUsers;
-
-    @SerializedName("mini_game_create_role_cost")
-    private Long miniGameCreateRoleCost;
-
-    @SerializedName("mini_game_retention_d1")
-    private Long miniGameRetentionD1;
-
-    @SerializedName("mini_game_key_page_viewers")
-    private Long miniGameKeyPageViewers;
-
-    @SerializedName("mini_game_key_page_view_cost")
-    private Long miniGameKeyPageViewCost;
-
-    @SerializedName("mini_game_ad_monetization_amount")
-    private Long miniGameAdMonetizationAmount;
-
-    @SerializedName("mini_game_paying_amount_by_upload")
-    private Long miniGamePayingAmountByUpload;
-
-    @SerializedName("mini_game_paying_count_by_upload")
-    private Long miniGamePayingCountByUpload;
-
-    @SerializedName("consult_leave_info_cost")
-    private Long consultLeaveInfoCost;
-
-    @SerializedName("purchase_amount_with_coupon")
-    private Long purchaseAmountWithCoupon;
-
-    @SerializedName("purchase_amount_with_coupon_cost")
-    private Long purchaseAmountWithCouponCost;
-
-    @SerializedName("mini_game_paying_amount_click_d1_by_upload")
-    private Long miniGamePayingAmountClickD1ByUpload;
-
-    @SerializedName("mini_game_retention_d1_rate")
-    private Double miniGameRetentionD1Rate;
-
-    @SerializedName("mini_game_retention_d1_cost")
-    private Long miniGameRetentionD1Cost;
-
-    @SerializedName("key_page_view_rate")
-    private Double keyPageViewRate;
-
-    @SerializedName("wechat_cost_stage1")
-    private Long wechatCostStage1;
-
-    @SerializedName("wechat_cost_stage2")
-    private Long wechatCostStage2;
-
-    @SerializedName("wechat_deep_conversions_count_stage1")
-    private Long wechatDeepConversionsCountStage1;
-
-    @SerializedName("wechat_deep_conversions_count_stage2")
-    private Long wechatDeepConversionsCountStage2;
-
-    @SerializedName("wechat_shallow_conversions_count_stage1")
-    private Long wechatShallowConversionsCountStage1;
-
-    @SerializedName("wechat_shallow_conversions_count_stage2")
-    private Long wechatShallowConversionsCountStage2;
-
-    @SerializedName("activate_register_rate")
-    private Double activateRegisterRate;
-
-    @SerializedName("key_behavior_conversions_count")
-    private Long keyBehaviorConversionsCount;
-
-    @SerializedName("key_behavior_conversions_cost")
-    private Long keyBehaviorConversionsCost;
-
-    @SerializedName("key_behavior_conversions_rate")
-    private Double keyBehaviorConversionsRate;
-
-    @SerializedName("first_day_order_roi")
-    private Double firstDayOrderRoi;
-
-    @SerializedName("mini_game_ad_monetization_cost")
-    private Long miniGameAdMonetizationCost;
-
-    @SerializedName("mini_game_ad_monetization_roi")
-    private Double miniGameAdMonetizationRoi;
-
-    @SerializedName("mini_game_ad_monetization_arpu")
-    private Long miniGameAdMonetizationArpu;
-
-    @SerializedName("mini_game_paying_roi")
-    private Double miniGamePayingRoi;
-
-    @SerializedName("mini_game_paying_arpu")
-    private Long miniGamePayingArpu;
-
-    @SerializedName("request_conversions_count")
-    private Long requestConversionsCount;
-
-    @SerializedName("request_conversions_cost")
-    private Long requestConversionsCost;
-
-    @SerializedName("income_val_1")
-    private Long incomeVal1;
-
-    @SerializedName("income_val_3")
-    private Long incomeVal3;
-
-    @SerializedName("income_val_7")
-    private Long incomeVal7;
-
-    @SerializedName("income_val_14")
-    private Long incomeVal14;
-
-    @SerializedName("income_roi_1")
-    private Double incomeRoi1;
-
-    @SerializedName("income_roi_3")
-    private Double incomeRoi3;
-
-    @SerializedName("income_roi_7")
-    private Double incomeRoi7;
-
-    @SerializedName("income_roi_14")
-    private Double incomeRoi14;
-
-    @SerializedName("activated_total_payment_cost")
-    private Long activatedTotalPaymentCost;
-
-    @SerializedName("payment_amount_activated_d3")
-    private Long paymentAmountActivatedD3;
-
-    @SerializedName("payment_amount_activated_d7")
-    private Long paymentAmountActivatedD7;
-
-    @SerializedName("payment_amount_activated_d14")
-    private Long paymentAmountActivatedD14;
-
-    @SerializedName("payment_amount_activated_d30")
-    private Long paymentAmountActivatedD30;
-
-    @SerializedName("first_day_pay_count")
-    private Long firstDayPayCount;
-
-    @SerializedName("first_day_pay_cost")
-    private Long firstDayPayCost;
-
-    @SerializedName("first_day_first_pay_cost")
-    private Long firstDayFirstPayCost;
-
-    @SerializedName("first_day_first_pay_count")
-    private Long firstDayFirstPayCount;
-
-    @SerializedName("payment_cost_activated_d1")
-    private Long paymentCostActivatedD1;
-
-    @SerializedName("first_day_pay_amount")
-    private Long firstDayPayAmount;
-
-    @SerializedName("roi_activated_d1")
-    private Double roiActivatedD1;
-
-    @SerializedName("roi_activated_d3")
-    private Double roiActivatedD3;
-
-    @SerializedName("roi_activated_d7")
-    private Double roiActivatedD7;
-
-    @SerializedName("roi_activated_d14")
-    private Double roiActivatedD14;
-
-    @SerializedName("first_day_ad_pur_arppu_cost")
-    private Long firstDayAdPurArppuCost;
-
-    @SerializedName("first_day_pay_amount_arpu")
-    private Long firstDayPayAmountArpu;
-
-    @SerializedName("first_day_pay_amount_arppu")
-    private Long firstDayPayAmountArppu;
-
-    @SerializedName("roi_activated_d30")
-    private Double roiActivatedD30;
-
-    @SerializedName("first_day_first_pay_rate")
-    private Double firstDayFirstPayRate;
-
-    @SerializedName("mini_game_first_day_ad_monetization_users")
-    private Long miniGameFirstDayAdMonetizationUsers;
-
-    @SerializedName("mini_game_first_day_ad_monetization_amount")
-    private Long miniGameFirstDayAdMonetizationAmount;
-
-    @SerializedName("mini_game_first_day_ad_paying_cost")
-    private Long miniGameFirstDayAdPayingCost;
-
-    @SerializedName("mini_game_income_roi_1")
-    private Double miniGameIncomeRoi1;
-
-    @SerializedName("mini_game_first_day_ad_paying_arpu")
-    private Long miniGameFirstDayAdPayingArpu;
-
-    @SerializedName("mini_game_paying_users_d1")
-    private Long miniGamePayingUsersD1;
-
-    @SerializedName("mini_game_paying_amount_d1")
-    private Long miniGamePayingAmountD1;
-
-    @SerializedName("mini_game_first_day_paying_roi")
-    private Double miniGameFirstDayPayingRoi;
-
-    @SerializedName("mini_game_paying_amount_d1_by_upload")
-    private Long miniGamePayingAmountD1ByUpload;
-
-    @SerializedName("mixed_monetization_roi_d1")
-    private Double mixedMonetizationRoiD1;
-
-    @SerializedName("mixed_monetization_roi_d3")
-    private Double mixedMonetizationRoiD3;
-
-    @SerializedName("mixed_monetization_roi_d7")
-    private Double mixedMonetizationRoiD7;
-
-    @SerializedName("mixed_monetization_roi_d14")
-    private Double mixedMonetizationRoiD14;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d1")
-    private Double miniGameMixedMonetizationRoiD1;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d1_by_reporting")
-    private Double miniGameMixedMonetizationRoiD1ByReporting;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d3")
-    private Double miniGameMixedMonetizationRoiD3;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d3_by_reporting")
-    private Double miniGameMixedMonetizationRoiD3ByReporting;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d7")
-    private Double miniGameMixedMonetizationRoiD7;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d7_by_reporting")
-    private Double miniGameMixedMonetizationRoiD7ByReporting;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d14")
-    private Double miniGameMixedMonetizationRoiD14;
-
-    @SerializedName("mini_game_mixed_monetization_roi_d14_by_reporting")
-    private Double miniGameMixedMonetizationRoiD14ByReporting;
-
-    @SerializedName("ad_paying_users_d1")
-    private Long adPayingUsersD1;
-
-    @SerializedName("ad_paying_cost_d1")
-    private Long adPayingCostD1;
-
-    @SerializedName("ad_pur_arpu_cost_d1")
-    private Long adPurArpuCostD1;
-
-    @SerializedName("ad_monetization_penetration_rat_d1")
-    private Double adMonetizationPenetrationRatD1;
-
-    @SerializedName("mini_game_paying_arpu_d1")
-    private Long miniGamePayingArpuD1;
-
-    @SerializedName("web_add_to_cart_count")
-    private Long webAddToCartCount;
-
-    @SerializedName("web_add_to_cart_cost")
-    private Long webAddToCartCost;
-
-    @SerializedName("preview_conversions_count")
-    private Long previewConversionsCount;
-
-    @SerializedName("preview_deep_conversions_count")
-    private Long previewDeepConversionsCount;
-
-    @SerializedName("promoted_object_type")
-    private String promotedObjectType;
-
-    @SerializedName("promoted_object_id")
-    private String promotedObjectId;
-
-    @SerializedName("nickname_click_user_count")
-    private Long nicknameClickUserCount;
-
-    @SerializedName("poi_click_user_count")
-    private Long poiClickUserCount;
-
-    @SerializedName("platform_key_page_view_user_count")
-    private Long platformKeyPageViewUserCount;
-
-    @SerializedName("platform_key_page_avg_view_per_user")
-    private Double platformKeyPageAvgViewPerUser;
-
-    @SerializedName("platform_key_page_view_duration")
-    private Double platformKeyPageViewDuration;
-
-    @SerializedName("cpn_click_button_cost")
-    private Long cpnClickButtonCost;
-
-    @SerializedName("praise_user_count")
-    private Long praiseUserCount;
-
-    @SerializedName("comment_user_count")
-    private Long commentUserCount;
-
-    @SerializedName("order_count")
-    private Long orderCount;
-
-    @SerializedName("order_rate")
-    private Double orderRate;
-
-    @SerializedName("quest_reservation_pv_cost")
-    private Long questReservationPvCost;
-
-    @SerializedName("leads_rate")
-    private Double leadsRate;
-
-    @SerializedName("leads_user_count")
-    private Long leadsUserCount;
-
-    @SerializedName("leads_cost")
-    private Long leadsCost;
-
-    @SerializedName("leads_user_rate")
-    private Double leadsUserRate;
-
-    @SerializedName("valid_leads_cost")
-    private Long validLeadsCost;
-
-    @SerializedName("valid_leads_rate")
-    private Double validLeadsRate;
-
-    @SerializedName("page_consult_user_count")
-    private Long pageConsultUserCount;
-
-    @SerializedName("valid_page_consult_user_count")
-    private Long validPageConsultUserCount;
-
-    @SerializedName("withdr_dep_web_user_count")
-    private Long withdrDepWebUserCount;
-
-    @SerializedName("wechat_minigame_register_cost")
-    private Long wechatMinigameRegisterCost;
-
-    @SerializedName("wechat_minigame_register_rate")
-    private Double wechatMinigameRegisterRate;
-
-    @SerializedName("wechat_minigame_arpu")
-    private Double wechatMinigameArpu;
-
-    @SerializedName("wechat_minigame_retention_count")
-    private Long wechatMinigameRetentionCount;
-
-    @SerializedName("wechat_minigame_checkout_count")
-    private Long wechatMinigameCheckoutCount;
-
-    @SerializedName("wechat_minigame_checkout_amount")
-    private Long wechatMinigameCheckoutAmount;
-
-    @SerializedName("official_account_follow_count")
-    private Long officialAccountFollowCount;
-
-    @SerializedName("official_account_follow_cost")
-    private Long officialAccountFollowCost;
-
-    @SerializedName("official_account_follow_rate")
-    private Double officialAccountFollowRate;
-
-    @SerializedName("official_account_register_user_count")
-    private Long officialAccountRegisterUserCount;
-
-    @SerializedName("official_account_register_rate")
-    private Double officialAccountRegisterRate;
-
-    @SerializedName("official_account_register_cost")
-    private Long officialAccountRegisterCost;
-
-    @SerializedName("official_account_register_amount")
-    private Long officialAccountRegisterAmount;
-
-    @SerializedName("official_account_register_roi")
-    private Long officialAccountRegisterRoi;
-
-    @SerializedName("official_account_apply_count")
-    private Long officialAccountApplyCount;
-
-    @SerializedName("official_account_apply_user_count")
-    private Long officialAccountApplyUserCount;
-
-    @SerializedName("official_account_apply_rate")
-    private Double officialAccountApplyRate;
-
-    @SerializedName("official_account_apply_cost")
-    private Long officialAccountApplyCost;
-
-    @SerializedName("official_account_apply_amount")
-    private Long officialAccountApplyAmount;
-
-    @SerializedName("official_account_apply_roi")
-    private Long officialAccountApplyRoi;
-
-    @SerializedName("official_account_order_count")
-    private Long officialAccountOrderCount;
-
-    @SerializedName("official_account_first_day_order_count")
-    private Long officialAccountFirstDayOrderCount;
-
-    @SerializedName("official_account_order_user_count")
-    private Long officialAccountOrderUserCount;
-
-    @SerializedName("official_account_order_rate")
-    private Double officialAccountOrderRate;
-
-    @SerializedName("official_account_order_cost")
-    private Long officialAccountOrderCost;
-
-    @SerializedName("official_account_order_amount")
-    private Long officialAccountOrderAmount;
-
-    @SerializedName("official_account_first_day_order_amount")
-    private Long officialAccountFirstDayOrderAmount;
-
-    @SerializedName("official_account_order_roi")
-    private Long officialAccountOrderRoi;
-
-    @SerializedName("official_account_consult_count")
-    private Long officialAccountConsultCount;
-
-    @SerializedName("official_account_reader_count")
-    private Long officialAccountReaderCount;
-
-    @SerializedName("official_account_credit_apply_user_count")
-    private Long officialAccountCreditApplyUserCount;
-
-    @SerializedName("official_account_credit_user_count")
-    private Long officialAccountCreditUserCount;
-
-    @SerializedName("coupon_get_cost")
-    private Long couponGetCost;
-
-    @SerializedName("coupon_get_rate")
-    private Double couponGetRate;
-
-    @SerializedName("coupon_use_count")
-    private Long couponUseCount;
-
-    @SerializedName("forward_user_count")
-    private Long forwardUserCount;
-
-    @SerializedName("video_outer_play_user_count")
-    private Long videoOuterPlayUserCount;
-
-    @SerializedName("video_inner_play_user_count")
-    private Long videoInnerPlayUserCount;
-
-    @SerializedName("poi_id")
-    private String poiId;
-}

+ 20 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/dto/AdStatOfDayDWDDTO.java

@@ -0,0 +1,20 @@
+package flink.zanxiangnet.ad.monitoring.pojo.dto;
+
+import flink.zanxiangnet.ad.monitoring.pojo.entity.AdStatOfDayDWD;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AdStatOfDayDWDDTO {
+    private LocalDate startDate;
+    private LocalDate endDate;
+
+    private AdStatOfDayDWD adStatOfDayDWD;
+}

+ 21 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/dto/AdStatOfDayODSDTO.java

@@ -0,0 +1,21 @@
+package flink.zanxiangnet.ad.monitoring.pojo.dto;
+
+import flink.zanxiangnet.ad.monitoring.pojo.entity.AdDataOfDayODS;
+import flink.zanxiangnet.ad.monitoring.pojo.entity.AdStatOfDayDWD;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AdStatOfDayODSDTO {
+    private LocalDate startDate;
+    private LocalDate endDate;
+
+    private AdDataOfDayODS adDataOfDayODS;
+}

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

@@ -0,0 +1,470 @@
+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 java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 原始数据
+ * 每 5分钟拉取的广告原始数据
+ */
+@Data
+@MaxComputeTable("ad_data_of_hour_ods")
+public class AdDataOfHourODS implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 统计日期(用于 MaxCompute分区)
+     */
+    @MaxComputeColumn(isPartitioned = true)
+    @SerializedName("stat_day")
+    private String statDay;
+
+    /**
+     * 统计的小时
+     */
+    @SerializedName("hour")
+    private Integer hour;
+
+    /**
+     * 统计发起时间
+     */
+    @SerializedName("stat_time")
+    private Long statTime;
+
+    /**
+     * 应用下的账号 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")
+    private Double costDeviationRate;
+
+    /**
+     * 消耗
+     */
+    @SerializedName("cost")
+    private Long cost;
+
+    /**
+     * 赔付金额。智能优化成本保障政策下,广告超成本时的赔付金额。
+     */
+    @SerializedName("compensation_amount")
+    private Long compensationAmount;
+
+    /**
+     * 曝光次数。用户观看广告的次数。
+     */
+    @SerializedName("view_count")
+    private Long viewCount;
+
+    /**
+     * 千次曝光成本。平均每千次曝光的花费。
+     */
+    @SerializedName("thousand_display_price")
+    private Long thousandDisplayPrice;
+
+    /**
+     * 人均曝光次数。每个用户观看广告的平均次数。
+     */
+    @SerializedName("avg_view_per_user")
+    private Double avgViewPerUser;
+
+    /**
+     * 点击次数。用户在广告外层进行点击操作的次数。包括点击图片/视频,及朋友圈广告“文字链、头像、昵称、门店、选择按钮”等所有广告外层区域的点击。
+     */
+    @SerializedName("valid_click_count")
+    private Long validClickCount;
+
+    /**
+     * 点击率。看到广告后执行点击操作的百分比。计算逻辑:广告点击次数/广告曝光次数。
+     */
+    @SerializedName("ctr")
+    private Double ctr;
+
+    /**
+     * 点击均价。一次广告点击的平均花费。计算逻辑:广告花费/广告点击次数。
+     */
+    @SerializedName("cpc")
+    private Long cpc;
+
+    /**
+     * 可转化点击次数。朋友圈:可转化点击是指可能产生转化的外层点击次数。对于“公众号推广”的广告,包括外层的公众号头像、公众号昵称、详情页查看、原生推广页查看; 对于其他类型的广告,包括外层的详情页查看和原生推广页查看。公众号:可转化点击是指可能产生转化的点击次数。
+     */
+    @SerializedName("valuable_click_count")
+    private Long valuableClickCount;
+
+    /**
+     * 可转化点击率。用户看到广告后执行可转化点击操作的百分比。计算逻辑:广告可转化点击次数/广告曝光次数。
+     */
+    @SerializedName("valuable_click_rate")
+    private Double valuableClickRate;
+
+    /**
+     * 可转化点击成本。一次可转化点击的平均花费。计算逻辑:广告花费/可转化点击次数。
+     */
+    @SerializedName("valuable_click_cost")
+    private Long valuableClickCost;
+
+    /**
+     * 转化目标量。「转化目标」的具体数量,代表该广告的转化效果量级。
+     */
+    @SerializedName("conversions_count")
+    private Long conversionsCount;
+
+    /**
+     * 转化目标成本。广告产生一次转化目标的平均费用。计算逻辑:广告花费/转化目标量。
+     */
+    @SerializedName("conversions_cost")
+    private Long conversionsCost;
+
+    /**
+     * 目标转化率。朋友圈:转化目标量/可转化点击次数。公众号:转化目标量/点击次数。
+     */
+    @SerializedName("conversions_rate")
+    private Double conversionsRate;
+
+    /**
+     * 深度转化目标量-灰度中。根据您选择的深度智能优化目标,该广告对应的具体数量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_count")
+    private Long deepConversionsCount;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost")
+    private Long deepConversionsCost;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate")
+    private Double deepConversionsRate;
+
+    /**
+     * 下单量。用户通过该广告进行商品成交(如下单提交、在线支付)的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_count")
+    private Long orderCount;
+
+    /**
+     * 首日新增下单量。广告推广获取的用户,点击广告当日,带来的下单次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_count")
+    private Long firstDayOrderCount;
+
+    /**
+     * 下单成本(次数)。产生一次下单的成本。
+     */
+    @SerializedName("web_order_cost")
+    private Long webOrderCost;
+
+    /**
+     * 下单率。一次点击到下单的转化率。
+     */
+    @SerializedName("order_rate")
+    private Double orderRate;
+
+    /**
+     * 下单金额。广告带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_amount")
+    private Long orderAmount;
+
+    /**
+     * 首日新增下单金额。广告推广获取的用户,点击广告当日,带来的总订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("first_day_order_amount")
+    private Long firstDayOrderAmount;
+
+    /**
+     * 下单客单价。下单金额/下单量。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_unit_price")
+    private Long orderUnitPrice;
+
+    /**
+     * 下单ROI。下单金额/广告花费。接入转化跟踪后可统计。
+     */
+    @SerializedName("order_roi")
+    private Double orderRoi;
+
+    /**
+     * 签收次数。签收从广告主处购买的商品的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("sign_in_count")
+    private Long signInCount;
+
+    /**
+     * 加企业微信客服人数。添加企业微信好友成功的独立用户数。
+     */
+    @SerializedName("scan_follow_count")
+    private Long scanFollowCount;
+
+    /**
+     * 小游戏注册人数。通过广告首次登录小游戏的独立用户数。
+     */
+    @SerializedName("wechat_app_register_uv")
+    private Long wechatAppRegisterUv;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @SerializedName("wechat_minigame_register_cost")
+    private Long wechatMinigameRegisterCost;
+
+    /**
+     * 小游戏注册率。一次点击到小游戏注册的转化率。
+     */
+    @SerializedName("wechat_minigame_register_rate")
+    private Double wechatMinigameRegisterRate;
+
+    /**
+     * 首日新增广告ARPU。广告带来的注册用户,在注册当日,产生的平均广告变现收入。注:该指标天更新,可以查看昨天及以前的数据。
+     */
+    @SerializedName("wechat_minigame_arpu")
+    private Double wechatMinigameArpu;
+
+    /**
+     * 小游戏次留人数。通过广告首次登录小游戏,并在第二天再次登录的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_retention_count")
+    private Long wechatMinigameRetentionCount;
+
+    /**
+     * 小游戏付费次数。通过广告进入小游戏并完成付费的次数。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_count")
+    private Long wechatMinigameCheckoutCount;
+
+    /**
+     * 小游戏付费金额。通过广告进入小游戏并完成付费的金额。接入转化跟踪后可统计。
+     */
+    @SerializedName("wechat_minigame_checkout_amount")
+    private Long wechatMinigameCheckoutAmount;
+
+    /**
+     * 公众号关注次数。用户通过广告关注公众号成功的次数。
+     */
+    @SerializedName("official_account_follow_count")
+    private Long officialAccountFollowCount;
+
+    /**
+     * 公众号关注成本(次数)。产生一次公众号关注的成本。
+     */
+    @SerializedName("official_account_follow_cost")
+    private Long officialAccountFollowCost;
+
+    /**
+     * 公众号关注率。一次点击到公众号关注的转化率。
+     */
+    @SerializedName("official_account_follow_rate")
+    private Double officialAccountFollowRate;
+
+    /**
+     * 公众号内注册人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的注册行为的人数(UV)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_user_count")
+    private Long officialAccountRegisterUserCount;
+
+    /**
+     * 公众号内注册比例。公众号内注册独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_rate")
+    private Double officialAccountRegisterRate;
+
+    /**
+     * 公众号内注册成本。广告花费/广告产生的注册行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_cost")
+    private Long officialAccountRegisterCost;
+
+    /**
+     * 公众号内注册订单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的订单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_amount")
+    private Long officialAccountRegisterAmount;
+
+    /**
+     * 公众号内注册ROI。注册产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_register_roi")
+    private Long officialAccountRegisterRoi;
+
+    /**
+     * 公众号内填单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_count")
+    private Long officialAccountApplyCount;
+
+    /**
+     * 公众号内填单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_user_count")
+    private Long officialAccountApplyUserCount;
+
+    /**
+     * 公众号内填单比例。公众号内填单的独立用户数/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_rate")
+    private Double officialAccountApplyRate;
+
+    /**
+     * 公众号内填单成本。广告花费/广告产生的填单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_cost")
+    private Long officialAccountApplyCost;
+
+    /**
+     * 公众号内填单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的填单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放)。
+     */
+    @SerializedName("official_account_apply_amount")
+    private Long officialAccountApplyAmount;
+
+    /**
+     * 公众号内填单ROI。填单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_apply_roi")
+    private Long officialAccountApplyRoi;
+
+    /**
+     * 公众号内下单次数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_count")
+    private Long officialAccountOrderCount;
+
+    /**
+     * 首日公众号内下单次数。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为数量。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_count")
+    private Long officialAccountFirstDayOrderCount;
+
+    /**
+     * 公众号内下单人数。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的独立用户数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_user_count")
+    private Long officialAccountOrderUserCount;
+
+    /**
+     * 公众号内下单比例。公众号内下单独立用户数(UV)/公众号关注次数。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_rate")
+    private Double officialAccountOrderRate;
+
+    /**
+     * 公众号内下单成本。广告花费/广告产生的下单行为数量。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_cost")
+    private Long officialAccountOrderCost;
+
+    /**
+     * 公众号内下单金额。用户通过关注类广告关注公众号后,在公众号内部产生了广告主定义的下单行为的订单金额(即销售额)。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_amount")
+    private Long officialAccountOrderAmount;
+
+    /**
+     * 首日公众号内下单金额。广告推广获取的用户,在关注公众号当日,在公众号内部产生了广告主定义的下单行为订单金额(即销售额)。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_first_day_order_amount")
+    private Long officialAccountFirstDayOrderAmount;
+
+    /**
+     * 公众号内下单ROI。下单产生的订单金额累计/广告花费。接入转化跟踪后可统计(公众号接入暂未全量开放) 。
+     */
+    @SerializedName("official_account_order_roi")
+    private Long officialAccountOrderRoi;
+
+    /**
+     * 公众号内发消息人数。用户关注公众号后,在公众号对话框内发送消息的独立用户数。
+     */
+    @SerializedName("official_account_consult_count")
+    private Long officialAccountConsultCount;
+
+    /**
+     * 阅读粉丝量。近3日新增的粉丝中产生阅读行为的用户数。
+     */
+    @SerializedName("official_account_reader_count")
+    private Long officialAccountReaderCount;
+
+    /**
+     * 公众号内进件人数。在公众号内完整提交贷款申请资料的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_apply_user_count")
+    private Long officialAccountCreditApplyUserCount;
+
+    /**
+     * 公众号内授信人数。在公众号内完整提交贷款申请资料,并通过放款方的资质审核的独立用户数。接入转化跟踪后可统计。
+     */
+    @SerializedName("official_account_credit_user_count")
+    private Long officialAccountCreditUserCount;
+
+    /**
+     * 广告分享次数。用户将广告落地页分享给好友和朋友圈的次数。
+     */
+    @SerializedName("forward_count")
+    private Long forwardCount;
+
+    /**
+     * 广告分享人数。将广告落地页分享给好友和朋友圈的独立用户数。
+     */
+    @SerializedName("forward_user_count")
+    private Long forwardUserCount;
+
+    /**
+     * 不感兴趣点击次数。用户点击“不感兴趣”的次数。
+     */
+    @SerializedName("no_interest_count")
+    private Long noInterestCount;
+}

+ 7 - 0
flink-ad-monitoring/src/main/java/flink/zanxiangnet/ad/monitoring/pojo/entity/AdDataOfMinuteODS.java

@@ -7,6 +7,7 @@ import flink.zanxiangnet.ad.monitoring.maxcompute.bean.annotation.MaxComputeTabl
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 原始数据
@@ -78,6 +79,12 @@ public class AdDataOfMinuteODS implements Serializable {
     @SerializedName("ad_id")
     private Long adId;
 
+    /**
+     * 数据创建时间
+     */
+    @SerializedName("create_time")
+    private Date createTime;
+
     /**
      * 当日成本偏差。反映广告今日的实际成本与目标成本直接的差异,注:该项成本相关数据按小时更新,与实时更新的「转化目标成本」数据存在出入属于正常情况。
      */

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

@@ -0,0 +1,1033 @@
+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 java.io.Serializable;
+import java.util.Date;
+
+@Data
+@MaxComputeTable("ad_data_of_day_ods")
+public class AdStatOfDayDWD 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;
+
+    /**
+     * 广告组 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_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_total")
+    private Long deepConversionsCostTotal;
+
+    /**
+     * 深度转化目标成本-灰度中。根据您选择的深度智能优化目标,该广告产生一次转化的平均费用。计算逻辑:广告花费/深度转化目标量。部分需接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_cost_day")
+    private Long deepConversionsCostDay;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @SerializedName("deep_conversions_rate_total")
+    private Double deepConversionsRateTotal;
+
+    /**
+     * 深度目标转化率-灰度中。朋友圈:深度转化目标量/可转化点击次数。公众号:深度转化目标量/点击次数。指标随深度转化功能灰度中。接入转化跟踪后可统计。
+     */
+    @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_total")
+    private Long wechatMinigameRegisterCostTotal;
+
+    /**
+     * 小游戏注册成本(人数)。产生一个小游戏注册人数的成本。
+     */
+    @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;
+
+    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;
+    }
+}

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

@@ -1,7 +1,11 @@
 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 flink.zanxiangnet.ad.monitoring.util.NumberUtil;
 import lombok.Data;
+import org.springframework.beans.BeanUtils;
 
 import java.time.LocalDate;
 
@@ -9,11 +13,13 @@ import java.time.LocalDate;
  * 广告维度的小时统计数据
  */
 @Data
+@MaxComputeTable("ad_stat_of_hour_dwd")
 public class AdStatOfHourDWD {
 
     /**
      * 统计的日期(用于 MaxCompute分区)
      */
+    @MaxComputeColumn(isPartitioned = true)
     @SerializedName("stat_day")
     private String statDay;
 
@@ -1198,4 +1204,157 @@ public class AdStatOfHourDWD {
      */
     @SerializedName("no_interest_count_hour")
     private Long noInterestCountHour;
+
+    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());
+        return adStatOfHour;
+    }
+
+    private AdStatOfHourDWD reduce(AdStatOfHourDWD value1, AdStatOfHourDWD value2) {
+        AdStatOfHourDWD result = new AdStatOfHourDWD();
+        BeanUtils.copyProperties(result, value2);
+        //??
+        result.setCostDeviationRateAll(NumberUtil.add(value1.getCostDeviationRateHour(), value2.getCostDeviationRateHour()));
+        result.setCostTotal(NumberUtil.add(value1.getCostHour(), value2.getCostHour()));
+        result.setCompensationAmountTotal(NumberUtil.add(value1.getCompensationAmountHour(), value2.getCompensationAmountHour()));
+        result.setViewCountTotal(NumberUtil.add(value1.getViewCountHour(), value2.getViewCountHour()));
+        //
+        result.setThousandDisplayPriceAll(NumberUtil.add(value1.getThousandDisplayPriceHour(), value2.getThousandDisplayPriceHour()));
+        //
+        result.setAvgViewPerUserAll(NumberUtil.add(value1.getAvgViewPerUserHour(), value2.getAvgViewPerUserHour()));
+        result.setValidClickCountTotal(NumberUtil.add(value1.getValidClickCountHour(), value2.getValidClickCountHour()));
+        //
+        result.setCtrAll(NumberUtil.add(value1.getCtrHour(), value2.getCtrHour()));
+        //
+        result.setCpcAll(NumberUtil.add(value1.getCpcHour(), value2.getCpcHour()));
+        result.setValuableClickCountTotal(NumberUtil.add(value1.getValuableClickCountHour(), value2.getValuableClickCountHour()));
+        //
+        result.setValuableClickRateAll(NumberUtil.add(value1.getValuableClickRateHour(), value2.getValuableClickRateHour()));
+        //
+        result.setValuableClickCostAll(NumberUtil.add(value1.getValuableClickCostHour(), value2.getValuableClickCostHour()));
+        result.setConversionsCountTotal(NumberUtil.add(value1.getConversionsCountHour(), value2.getConversionsCountHour()));
+        result.setConversionsCostAll(NumberUtil.add(value1.getConversionsCostHour(), value2.getConversionsCostHour()));
+        result.setConversionsRateAll(NumberUtil.add(value1.getConversionsRateHour(), value2.getConversionsRateHour()));
+        result.setDeepConversionsCountTotal(NumberUtil.add(value1.getDeepConversionsCountHour(), value2.getDeepConversionsCountHour()));
+        result.setDeepConversionsCostAll(NumberUtil.add(value1.getDeepConversionsCostHour(), value2.getDeepConversionsCostHour()));
+        result.setDeepConversionsRateAll(NumberUtil.add(value1.getDeepConversionsRateHour(), value2.getDeepConversionsRateHour()));
+        result.setOrderCountTotal(NumberUtil.add(value1.getOrderCountHour(), value2.getOrderCountHour()));
+        result.setFirstDayOrderCountTotal(NumberUtil.add(value1.getFirstDayOrderCountHour(), value2.getFirstDayOrderCountHour()));
+        result.setWebOrderCostAll(NumberUtil.add(value1.getWebOrderCostHour(), value2.getWebOrderCostHour()));
+        result.setOrderRateAll(NumberUtil.add(value1.getOrderRateHour(), value2.getOrderRateHour()));
+        result.setOrderAmountTotal(NumberUtil.add(value1.getOrderAmountHour(), value2.getOrderAmountHour()));
+        result.setFirstDayOrderAmountTotal(NumberUtil.add(value1.getFirstDayOrderAmountHour(), value2.getFirstDayOrderAmountHour()));
+        result.setOrderUnitPriceAll(NumberUtil.add(value1.getOrderUnitPriceHour(), value2.getOrderUnitPriceHour()));
+        result.setOrderRoiAll(NumberUtil.add(value1.getOrderRoiHour(), value2.getOrderRoiHour()));
+        result.setSignInCountTotal(NumberUtil.add(value1.getSignInCountHour(), value2.getSignInCountHour()));
+        result.setScanFollowCountTotal(NumberUtil.add(value1.getScanFollowCountHour(), value2.getScanFollowCountHour()));
+        result.setWechatAppRegisterUvTotal(NumberUtil.add(value1.getWechatAppRegisterUvHour(), value2.getWechatAppRegisterUvHour()));
+        result.setWechatMinigameRegisterCostAll(NumberUtil.add(value1.getWechatMinigameRegisterCostHour(), value2.getWechatMinigameRegisterCostHour()));
+        result.setWechatMinigameRegisterRateAll(NumberUtil.add(value1.getWechatMinigameRegisterRateHour(), value2.getWechatMinigameRegisterRateHour()));
+        result.setWechatMinigameArpuAll(NumberUtil.add(value1.getWechatMinigameArpuHour(), value2.getWechatMinigameArpuHour()));
+        result.setWechatMinigameRetentionCountTotal(NumberUtil.add(value1.getWechatMinigameRetentionCountHour(), value2.getWechatMinigameRetentionCountHour()));
+        result.setWechatMinigameCheckoutCountTotal(NumberUtil.add(value1.getWechatMinigameCheckoutCountHour(), value2.getWechatMinigameCheckoutCountHour()));
+        result.setWechatMinigameCheckoutAmountTotal(NumberUtil.add(value1.getWechatMinigameCheckoutAmountHour(), value2.getWechatMinigameCheckoutAmountHour()));
+        result.setOfficialAccountFollowCountTotal(NumberUtil.add(value1.getOfficialAccountFollowCountHour(), value2.getOfficialAccountFollowCountHour()));
+        result.setOfficialAccountFollowRateAll(NumberUtil.add(value1.getOfficialAccountFollowRateHour(), value2.getOfficialAccountFollowRateHour()));
+        result.setOfficialAccountRegisterUserCountTotal(NumberUtil.add(value1.getOfficialAccountRegisterUserCountHour(), value2.getOfficialAccountRegisterUserCountHour()));
+        result.setOfficialAccountRegisterRateAll(NumberUtil.add(value1.getOfficialAccountRegisterRateHour(), value2.getOfficialAccountRegisterRateHour()));
+        result.setOfficialAccountRegisterCostAll(NumberUtil.add(value1.getOfficialAccountRegisterCostHour(), value2.getOfficialAccountRegisterCostHour()));
+        result.setOfficialAccountRegisterAmountTotal(NumberUtil.add(value1.getOfficialAccountRegisterAmountHour(), value2.getOfficialAccountRegisterAmountHour()));
+        result.setOfficialAccountRegisterRoiAll(NumberUtil.add(value1.getOfficialAccountRegisterRoiHour(), value2.getOfficialAccountRegisterRoiHour()));
+        result.setOfficialAccountApplyCountTotal(NumberUtil.add(value1.getOfficialAccountApplyCountHour(), value2.getOfficialAccountApplyCountHour()));
+        result.setOfficialAccountApplyUserCountTotal(NumberUtil.add(value1.getOfficialAccountApplyUserCountHour(), value2.getOfficialAccountApplyUserCountHour()));
+        result.setOfficialAccountApplyRateAll(NumberUtil.add(value1.getOfficialAccountApplyRateHour(), value2.getOfficialAccountApplyRateHour()));
+        result.setOfficialAccountApplyCostAll(NumberUtil.add(value1.getOfficialAccountApplyCostHour(), value2.getOfficialAccountApplyCostHour()));
+        result.setOfficialAccountApplyAmountTotal(NumberUtil.add(value1.getOfficialAccountApplyAmountHour(), value2.getOfficialAccountApplyAmountHour()));
+        result.setOfficialAccountApplyRoiAll(NumberUtil.add(value1.getOfficialAccountApplyRoiHour(), value2.getOfficialAccountApplyRoiHour()));
+        result.setOfficialAccountOrderCountTotal(NumberUtil.add(value1.getOfficialAccountOrderCountHour(), value2.getOfficialAccountOrderCountHour()));
+        result.setOfficialAccountFirstDayOrderCountTotal(NumberUtil.add(value1.getOfficialAccountFirstDayOrderCountHour(), value2.getOfficialAccountFirstDayOrderCountHour()));
+        result.setOfficialAccountOrderUserCountTotal(NumberUtil.add(value1.getOfficialAccountOrderUserCountHour(), value2.getOfficialAccountOrderUserCountHour()));
+        result.setOfficialAccountOrderRateAll(NumberUtil.add(value1.getOfficialAccountOrderRateHour(), value2.getOfficialAccountOrderRateHour()));
+        result.setOfficialAccountOrderCostAll(NumberUtil.add(value1.getOfficialAccountOrderCostHour(), value2.getOfficialAccountOrderCostHour()));
+        result.setOfficialAccountOrderAmountTotal(NumberUtil.add(value1.getOfficialAccountOrderAmountHour(), value2.getOfficialAccountOrderAmountHour()));
+        result.setOfficialAccountFirstDayOrderAmountTotal(NumberUtil.add(value1.getOfficialAccountFirstDayOrderAmountHour(), value2.getOfficialAccountFirstDayOrderAmountHour()));
+        result.setOfficialAccountOrderRoiAll(NumberUtil.add(value1.getOfficialAccountOrderRoiHour(), value2.getOfficialAccountOrderRoiHour()));
+        result.setOfficialAccountConsultCountTotal(NumberUtil.add(value1.getOfficialAccountConsultCountHour(), value2.getOfficialAccountConsultCountHour()));
+        result.setOfficialAccountReaderCountTotal(NumberUtil.add(value1.getOfficialAccountReaderCountHour(), value2.getOfficialAccountReaderCountHour()));
+        result.setOfficialAccountCreditApplyUserCountTotal(NumberUtil.add(value1.getOfficialAccountCreditApplyUserCountHour(), value2.getOfficialAccountCreditApplyUserCountHour()));
+        result.setOfficialAccountCreditUserCountTotal(NumberUtil.add(value1.getOfficialAccountCreditUserCountHour(), value2.getOfficialAccountCreditUserCountHour()));
+        result.setForwardCountTotal(NumberUtil.add(value1.getForwardCountHour(), value2.getForwardCountHour()));
+        result.setForwardUserCountTotal(NumberUtil.add(value1.getForwardUserCountHour(), value2.getForwardUserCountHour()));
+        result.setNoInterestCountTotal(NumberUtil.add(value1.getNoInterestCountHour(), value2.getNoInterestCountHour()));
+        return result;
+    }
 }

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

@@ -15,6 +15,14 @@ public class DateUtil {
         return date.format(FORMAT_DATE);
     }
 
+    public static String formatLocalDateTime(LocalDateTime dateTime) {
+        return dateTime.format(FORMAT_DATETIME);
+    }
+
+    public static LocalDate parseLocalDate(String dateStr) {
+        return LocalDate.parse(dateStr, FORMAT_DATE);
+    }
+
     public static long localDateToSecond(LocalDate localDate) {
         return localDate.atStartOfDay(ZoneOffset.ofHours(8)).toEpochSecond();
     }
@@ -78,4 +86,15 @@ public class DateUtil {
     public static LocalDateTime dateToLocalDateTime(Date date) {
         return date.toInstant().atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
     }
+
+    /**
+     * 2个日期的时间间隔
+     *
+     * @param beginDate
+     * @param endDate
+     * @return
+     */
+    public static long intervalOfDays(LocalDate beginDate, LocalDate endDate) {
+        return endDate.toEpochDay() - beginDate.toEpochDay();
+    }
 }

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

@@ -1,7 +1,13 @@
 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
+kafka.groupId=ad_day_cost_group
+
+#kafka.servers=172.17.174.73:9092,172.17.174.72:9092
+#kafka.username=
+#kafka.password=
+#kafka.topic=ad_day_cost_topic
+#kafka.groupId=ad_day_consumer

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

@@ -1,7 +1,13 @@
 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
+kafka.groupId=ad_cost_group
+
+#kafka.servers=172.17.174.73:9092,172.17.174.72:9092
+#kafka.username=
+#kafka.password=
+#kafka.topic=ad_cost_topic
+#kafka.groupId=ad_minute_consumer

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

@@ -1,5 +1,10 @@
-maxCompute.accountId=LTAI5tFuLw65UsH3tqru2K1h
-maxCompute.accountKey=p1F8my4ovgcEfs3HVORdmeLlLUUKRp
+#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.endpoint=http://service.cn-hangzhou.maxcompute.aliyun.com/api
-maxCompute.projectName=zx_ad_monitoring
+maxCompute.projectName=zx_test02
 maxCompute.tunnelEndpoint=http://dt.cn-hangzhou.maxcompute.aliyun.com