Sfoglia il codice sorgente

Merge branch 'video-dev' into test

hcst_sunzhen 5 anni fa
parent
commit
ec4ba827bd

+ 6 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedanceDailyMaterialReportRetryJob.java

@@ -45,6 +45,7 @@ public class BytedanceDailyMaterialReportRetryJob implements Job {
                         String startDate = retry.getStartDate();
                         String endDate = retry.getEndDate();
                         Long accountId = retry.getAccountId();
+                        Integer type = retry.getType();
                         CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(accountId));
                         log.info("头条素材报表重试定时任务,当前accountId为:" + token.getAccountId());
 
@@ -55,10 +56,12 @@ public class BytedanceDailyMaterialReportRetryJob implements Job {
                             start = DateUtils.addDay(startDate, i);
                             end = start;
                             //获取头条素材报表数据
-                            int code = bytedanceReportService.bytedanceMaterialReportRetry(token, start, end);
+                            int code = bytedanceReportService.bytedanceMaterialReportRetry(type, token, start, end);
                             if(code ==200 || code == 1){
-                                //重试成功清洗数据
-                                byteDanceVideoReportDailyService.videoInfoListByAccountId(start,end,accountId);
+                                if(type == 1){
+                                    //重试成功清洗数据
+                                    byteDanceVideoReportDailyService.videoInfoListByAccountId(start,end,accountId);
+                                }
                             }
                         }
                     } catch (Exception e) {

+ 67 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedanceDailyVideoMaterialReportAddJob.java

@@ -0,0 +1,67 @@
+package org.jeecg.modules.ctop.job;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.toutiao.modules.report.service.IBytedanceReportService;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 头条视频素材报表每天将前一天新绑定的账户数据从20200101开始跑到前一天
+ *
+ * @author sunzhen
+ */
+@Slf4j
+public class BytedanceDailyVideoMaterialReportAddJob implements Job {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IBytedanceReportService bytedanceReportService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        Date getDate = DateUtils.addDay(new Date(), -1);
+        String endDate = DateUtils.formatDate(getDate);
+        String startDate = "2020-01-01";
+        log.info("头条获取视频素材报表数据补充任务开始,任务时间:{}~{}",startDate,endDate);
+
+        List<CtopOauthToken> tokens = tokenService.getToutiaoTokenByCreateTime(endDate);
+        if (null == tokens || tokens.size() <= 0) {
+            log.info("头条获取素材报表数据任务执行失败:未获取到可用的token");
+            return;
+        }
+
+        final ExecutorService executorService = Executors.newFixedThreadPool(3);
+        tokens.forEach(token -> {
+            executorService.submit(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+
+                        Long days = DateUtils.getDiscrepantDays(startDate, endDate); //间隔天数
+                        String start = null;
+                        String end = null;
+                        for (int i = 0; i <= days; i++) {
+                            start = DateUtils.addDay(startDate, i);
+                            end = start;
+                            bytedanceReportService.bytedanceVideoMaterialReport(token, start, end);
+                        }
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    } finally {
+                    }
+                }
+            });
+        });
+
+    }
+}

+ 64 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedanceDailyVideoMaterialReportJob.java

@@ -0,0 +1,64 @@
+package org.jeecg.modules.ctop.job;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.toutiao.modules.report.service.IBytedanceReportService;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 头条视频素材报表按天跑前两天的数据任务
+ *
+ * @author sunzhen
+ */
+@Slf4j
+public class BytedanceDailyVideoMaterialReportJob implements Job {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IBytedanceReportService bytedanceReportService;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        Date getDate2 = DateUtils.addDay(new Date(), -2);
+        String date2 = DateUtils.formatDate(getDate2);
+
+        Date getDate = DateUtils.addDay(new Date(), -1);
+        String date = DateUtils.formatDate(getDate);
+        log.info("头条获取素材报表数据任务开始,任务时间:" + date2 + "~" + date);
+
+        List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+        if (null == tokens || tokens.size() <= 0) {
+            log.info("头条获取素材报表数据任务执行失败:未获取到可用的token");
+            return;
+        }
+
+        final ExecutorService executorService = Executors.newFixedThreadPool(3);
+        tokens.forEach(token -> {
+            executorService.submit(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        //获取头条视频素材报表两天前的数据
+                        bytedanceReportService.bytedanceVideoMaterialReport(token, date2, date2);
+                        //获取头条视频素材报表数据
+                        bytedanceReportService.bytedanceVideoMaterialReport(token, date, date);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    } finally {
+                    }
+                }
+            });
+        });
+
+    }
+}

+ 4 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedancePlanDailyReportLoadJob.java

@@ -35,6 +35,7 @@ public class BytedancePlanDailyReportLoadJob {
     @XxlJob("bytedancePlanDailyReport")
     public ReturnT<String> execute(String param) throws Exception {
         Date getDate = DateUtils.addDay(new Date(), -1);
+        Date getDate2 = DateUtils.addDay(new Date(), -2);//次留用
         //1:查询当日数据
         List<CtopOauthToken> tokens = tokenService.getTokenListByType(CtopAdConstant.PLATFORM_TYPE_BYTEDANCE);
         if (null == tokens || tokens.size() <= 0) {
@@ -49,6 +50,9 @@ public class BytedancePlanDailyReportLoadJob {
         planDailyReportService.cleanYzData(151);
         planDailyReportService.cleanChannelCodeData(235, getDate);
         planDailyReportService.cleanChannelCodeData(270, getDate);
+
+        //跑次留
+        tokens.forEach(token -> reportService.getAdvertiserPlanReport(token, getDate2, getDate2, CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY));
         return ReturnT.SUCCESS;
     }
 

+ 114 - 9
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/controller/BytedanceReportController.java

@@ -143,7 +143,7 @@ public class BytedanceReportController {
                 return result;
             }
 
-            final ExecutorService executorService = Executors.newFixedThreadPool(3);
+            final ExecutorService executorService = Executors.newFixedThreadPool(8);
             tokens.forEach(token -> {
                 executorService.submit(new Runnable() {
                     @Override
@@ -165,7 +165,8 @@ public class BytedanceReportController {
                         }
                     }
                 });
-            });
+            }
+            );
             ////
             Long endtime = System.currentTimeMillis();
             log.info("头条获取素材报表数据任务执行结束,执行耗时:{}秒", (endtime - starttime) / 1000);
@@ -189,12 +190,11 @@ public class BytedanceReportController {
                     @Override
                     public void run() {
                         try {
+                            Integer type = retry.getType();
                             String startDate = retry.getStartDate();
                             String endDate = retry.getEndDate();
                             Long accountId = retry.getAccountId();
                             CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(accountId));
-                            log.info("头条素材报表当前accountId为:" + token.getAccountId());
-                            //int code = bytedanceReportService.bytedanceMaterialReportRetry(token, startDate, endDate);
 
                             Long days = DateUtils.getDiscrepantDays(startDate, endDate); //间隔天数
                             String start = null;
@@ -203,10 +203,12 @@ public class BytedanceReportController {
                                 start = DateUtils.addDay(startDate, i);
                                 end = start;
                                 //获取头条素材报表数据
-                                int code = bytedanceReportService.bytedanceMaterialReportRetry(token, start, end);
+                                int code = bytedanceReportService.bytedanceMaterialReportRetry(type, token, start, end);
                                 if(code ==200 || code == 1){
-                                    //重试成功清洗数据
-                                    byteDanceVideoReportDailyService.videoInfoListByAccountId(start,end,accountId);
+                                    if(type == 1){
+                                        //重试成功清洗数据
+                                        byteDanceVideoReportDailyService.videoInfoListByAccountId(start,end,accountId);
+                                    }
                                 }
                             }
 
@@ -219,12 +221,11 @@ public class BytedanceReportController {
             ////
 
         } catch (Exception e) {
-            log.error("条获取素材报表失败数据任务重试失败");
+            log.error("条获取素材报表失败数据任务重试失败");
             e.printStackTrace();
             result.setSuccess(false);
         }
 
-        log.info("头条获取素材报表数据任务重试结束");
         return result;
     }
 
@@ -278,4 +279,108 @@ public class BytedanceReportController {
         return result;
     }
 
+
+    /**
+     * 头条视频素材报表--此接口仅有视频素材,异步拉取数据
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    @GetMapping("/bytedance/bytedanceVideoMaterialReport")
+    public Result bytedanceVideoMaterialReport(@RequestParam(name = "startDate") String startDate,
+                                                @RequestParam(name = "endDate") String endDate) {
+        Result result = new Result<>();
+        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)){
+            result.error500("开始时间和结束时间不能为空");
+            return result;
+        }
+        try {
+            log.info("头条获取视频素材报表数据任务执行开始");
+            Long starttime = System.currentTimeMillis();
+            List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+            if (null == tokens || tokens.size() <= 0) {
+                log.info("头条获取素材报表数据任务执行失败:未获取到可用的token");
+                return result;
+            }
+
+            final ExecutorService executorService = Executors.newFixedThreadPool(8);
+            tokens.forEach(token -> {
+                executorService.submit(new Runnable() {
+                           @Override
+                           public void run() {
+
+                               try {
+                                   //间隔天数
+                                   Long days = DateUtils.getDiscrepantDays(startDate, endDate);
+                                   String start = null;
+                                   String end = null;
+                                   for (int i = 0; i <= days; i++) {
+                                       start = DateUtils.addDay(startDate, i);
+                                       end = start;
+                                       //获取头条素材报表数据
+                                       bytedanceReportService.bytedanceVideoMaterialReport(token, start, end);
+                                   }
+                               } catch (Exception e) {
+                                   e.printStackTrace();
+                               }
+
+                           }
+                       });
+                    });
+            ////
+            Long endtime = System.currentTimeMillis();
+            log.info("头条获取视频素材报表数据任务执行结束,执行耗时:{}秒", (endtime - starttime) / 1000);
+        } catch (Exception e) {
+            log.error("头条获取视频素材报表数据任务执行结失败");
+            e.printStackTrace();
+            result.setSuccess(false);
+        }
+        return result;
+    }
+
+    /**
+     * 头条视频素材报表--此接口仅有视频素材,单个accountId拉取数据
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    @GetMapping("/bytedance/bytedanceVideoMaterialReportByAccountId")
+    public Result bytedanceVideoMaterialReportByAccountId(@RequestParam(name = "startDate") String startDate,
+                                               @RequestParam(name = "endDate") String endDate,
+                                               @RequestParam(name = "accountId") Long accountId) {
+        Result result = new Result<>();
+        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)||accountId==null){
+            result.error500("开始时间,结束时间和账户id不能为空");
+            return result;
+        }
+        try {
+            log.info("头条获取单个账户视频素材报表数据任务执行开始");
+            Long starttime = System.currentTimeMillis();
+            CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(accountId));
+            if (null == token ) {
+                log.info("头条获取单个账户视频素材报表数据任务执行失败:未获取到可用的token");
+                return result;
+            }
+
+            //间隔天数
+            Long days = DateUtils.getDiscrepantDays(startDate, endDate);
+            String start = null;
+            String end = null;
+            for (int i = 0; i <= days; i++) {
+                start = DateUtils.addDay(startDate, i);
+                end = start;
+                //获取头条素材报表数据
+                bytedanceReportService.bytedanceVideoMaterialReport(token, start, end);
+            }
+
+            Long endtime = System.currentTimeMillis();
+            log.info("头条获取视频素材报表数据任务执行结束,执行耗时:{}秒", (endtime - starttime) / 1000);
+        } catch (Exception e) {
+            log.error("头条获取视频素材报表数据任务执行结失败");
+            e.printStackTrace();
+            result.setSuccess(false);
+        }
+        return result;
+    }
+
 }

+ 1 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/entity/BytedanceReportMaterialRetry.java

@@ -58,4 +58,5 @@ public class BytedanceReportMaterialRetry {
     @ApiModelProperty(value = "updateTime")
 	private Date updateTime;
     private Integer statusCode;
+    private Integer type;
 }

+ 195 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/entity/BytedanceReportVideoMaterialDaily.java

@@ -0,0 +1,195 @@
+package cn.com.ctop.toutiao.modules.report.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.util.DateUtils;
+
+import java.math.BigDecimal;
+
+/**
+ * 头条视频素材日报表--仅包含视频素材
+ * @author sunzhen
+ */
+@Data
+@TableName("ctop_bytedance_report_video_material_daily")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_bytedance_report_video_material_daily对象", description="头条视频素材日报表--仅包含视频素材")
+public class BytedanceReportVideoMaterialDaily {
+
+	/**id*/
+	@TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+	private Long id;
+	/**账户id*/
+    @ApiModelProperty(value = "广告主id")
+	private Long accountId;
+	/**数据起始时间1*/
+    @ApiModelProperty(value = "数据时间")
+	private String statDatetime;
+	/**素材id*/
+	@ApiModelProperty(value = "素材id")
+	private Long materialId;
+	/**展现数据-点击数*/
+	@ApiModelProperty(value = "展现数据-点击数")
+	private Long click;
+	/**展现数据-总花费*/
+	@ApiModelProperty(value = "展现数据-总花费")
+	private BigDecimal cost;
+	/**展现数据-总花费*/
+	@ApiModelProperty(value = "展现数据-平均点击单价")
+	private BigDecimal avgClickCost;
+	/**转化数据-深度转化数*/
+	@ApiModelProperty(value = "转化数据-深度转化数")
+	private Long deepConvert;
+	/**转化数据-深度转化成本*/
+	@ApiModelProperty(value = "转化数据-深度转化成本")
+	private BigDecimal deepConvertCost;
+	/**转化数据-深度转化率*/
+	@ApiModelProperty(value = "转化数据-深度转化率")
+	private BigDecimal deepConvertRate;
+	/**互动数据-不感兴趣数*/
+	@ApiModelProperty(value = "互动数据-不感兴趣数")
+	private Long dislike;
+	/**互动数据-举报数*/
+	@ApiModelProperty(value = "互动数据-举报数")
+	private Long report;
+	/**视频数据-2秒播放率*/
+	@ApiModelProperty(value = "视频数据-2秒播放率")
+	private BigDecimal playDuration2sRate;
+	/**视频数据-3秒播放率*/
+	@ApiModelProperty(value = "视频数据-3秒播放率")
+	private BigDecimal playDuration3sRate;
+	/**视频数据-5秒播放率*/
+	@ApiModelProperty(value = "视频数据-5秒播放率")
+	private BigDecimal playDuration5sRate;
+	/**视频数据-10秒播放率*/
+	@ApiModelProperty(value = "视频数据-10秒播放率")
+	private BigDecimal playDuration10sRate;
+	/**视频数据-25%进度播放率*/
+	@ApiModelProperty(value = "视频数据-25%进度播放率")
+	private BigDecimal play25FeedBreakRate;
+	/**视频数据-50%进度播放率*/
+	@ApiModelProperty(value = "视频数据-50%进度播放率")
+	private BigDecimal play50FeedBreakRate;
+	/**视频数据-75%进度播放率*/
+	@ApiModelProperty(value = "视频数据-75%进度播放率")
+	private BigDecimal play75FeedBreakRate;
+	/**视频数据-99%进度播放率*/
+	@ApiModelProperty(value = "视频数据-99%进度播放率")
+	private BigDecimal play100FeedBreakRate;
+	/**展现数据-平均千次展现费用*/
+	@ApiModelProperty(value = "展现数据-平均千次展现费用")
+	private BigDecimal avgShowCost;
+	/**视频数据-播放数*/
+	@ApiModelProperty(value = "视频数据-播放数")
+	private Long totalPlay;
+	/**视频数据-有效播放数*/
+	@ApiModelProperty(value = "视频数据-有效播放数")
+	private Long validPlay;
+	/**互动数据-分享数*/
+	@ApiModelProperty(value = "互动数据-分享数")
+	private Long shareMaterial;
+	/**互动数据-评论数*/
+	@ApiModelProperty(value = "互动数据-评论数")
+	private Long commentMaterial;
+	/**互动数据-新增关注数*/
+	@ApiModelProperty(value = "互动数据-新增关注数")
+	private Long follow;
+	/**视频数据-有效播放成本*/
+	@ApiModelProperty(value = "视频数据-有效播放成本")
+	private BigDecimal validPlayCost;
+	/**转化数据-转化数*/
+	@ApiModelProperty(value = "转化数据-转化数")
+	private Long convertMaterial;
+	/**视频数据-播完率*/
+	@ApiModelProperty(value = "视频数据-播完率")
+	private BigDecimal playOverRate;
+	/**展现数据-点击率*/
+	@ApiModelProperty(value = "展现数据-点击率")
+	private BigDecimal ctr;
+	/**互动数据-点赞数*/
+	@ApiModelProperty(value = "互动数据-点赞数")
+	private Long likeMaterial;
+	/**展现数据-展示数*/
+	@ApiModelProperty(value = "展现数据-展示数")
+	private Long showMaterial;
+	/**转化数据-转化率*/
+	@ApiModelProperty(value = "转化数据-转化率")
+	private BigDecimal convertRate;
+	/**视频数据-播放完成数*/
+	@ApiModelProperty(value = "视频数据-播放完成数")
+	private Long playOver;
+	/**互动数据-私信数*/
+	@ApiModelProperty(value = "互动数据-私信数")
+	private Long messageAction;
+	/**视频数据-有效播放率*/
+	@ApiModelProperty(value = "视频数据-有效播放率")
+	private BigDecimal validPlayRate;
+	/**视频数据-平均单次播放时长*/
+	@ApiModelProperty(value = "视频数据-平均单次播放时长")
+	private BigDecimal averagePlayTimePerPlay;
+	/**转化数据-转化成本*/
+	@ApiModelProperty(value = "转化数据-转化成本")
+	private BigDecimal convertCost;
+	/***/
+	@ApiModelProperty(value = "")
+	private BigDecimal convertShowRate;
+
+	public BytedanceReportVideoMaterialDaily() {
+	}
+
+	public BytedanceReportVideoMaterialDaily(JSONObject detailJson, Long accountId) {
+		JSONObject dimensions = detailJson.getJSONObject("dimensions");
+		this.accountId = accountId;
+		this.setMaterialId(dimensions.getLong("material_id"));
+		this.setStatDatetime(dimensions.getDate("stat_datetime") == null ? null : DateUtils.formatDate(dimensions.getDate("stat_datetime"), "yyyy-MM-dd"));
+
+		JSONObject metrics = detailJson.getJSONObject("metrics");
+		this.setValidPlayCost(metrics.getBigDecimal("valid_play_cost"));
+		this.setClick(metrics.getLong("click"));
+		this.setDislike(metrics.getLong("dislike"));
+		this.setReport(metrics.getLong("report"));
+		this.setCost(metrics.getBigDecimal("cost"));
+		this.setAvgClickCost(metrics.getBigDecimal("avg_click_cost"));
+		this.setDeepConvert(metrics.getLong("deep_convert"));
+		this.setDeepConvertCost(metrics.getBigDecimal("deep_convert_cost"));
+		this.setDeepConvertRate(metrics.getBigDecimal("deep_convert_rate"));
+		this.setPlayDuration2sRate(metrics.getBigDecimal("play_duration_2s_rate"));
+		this.setPlayDuration3sRate(metrics.getBigDecimal("play_duration_3s_rate"));
+		this.setPlayDuration5sRate(metrics.getBigDecimal("play_duration_5s_rate"));
+		this.setPlayDuration10sRate(metrics.getBigDecimal("play_duration_10s_rate"));
+		this.setPlay25FeedBreakRate(metrics.getBigDecimal("play_25_feed_break_rate"));
+		this.setPlay50FeedBreakRate(metrics.getBigDecimal("play_50_feed_break_rate"));
+		this.setPlay75FeedBreakRate(metrics.getBigDecimal("play_75_feed_break_rate"));
+		this.setPlay100FeedBreakRate(metrics.getBigDecimal("play_100_feed_break_rate"));
+		this.setPlayOverRate(metrics.getBigDecimal("play_over_rate"));
+		this.setAvgShowCost(metrics.getBigDecimal("avg_show_cost"));
+		this.setTotalPlay(metrics.getLong("total_play"));
+		this.setValidPlay(metrics.getLong("valid_play"));
+		this.setShareMaterial(metrics.getLong("share"));
+		this.setCommentMaterial(metrics.getLong("comment"));
+		this.setFollow(metrics.getLong("follow"));
+		this.setValidPlayCost(metrics.getBigDecimal("valid_play_cost"));
+		this.setConvertMaterial(metrics.getLong("convert"));
+		this.setPlayOverRate(metrics.getBigDecimal("play_over_rate"));
+		this.setCtr(metrics.getBigDecimal("ctr"));
+		this.setLikeMaterial(metrics.getLong("like"));
+		this.setShowMaterial(metrics.getLong("show"));
+		this.setConvertRate(metrics.getBigDecimal("convert_rate"));
+		this.setPlayOver(metrics.getLong("play_over"));
+		this.setMessageAction(metrics.getLong("message_action"));
+		this.setValidPlayRate(metrics.getBigDecimal("valid_play_rate"));
+		this.setAveragePlayTimePerPlay(metrics.getBigDecimal("average_play_time_per_play"));
+		this.setConvertCost(metrics.getBigDecimal("convert_cost"));
+		this.setConvertShowRate(metrics.getBigDecimal("convert_show_rate"));
+	}
+
+}

+ 3 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/mapper/BytedanceReportMaterialDailyMapper.java

@@ -2,6 +2,7 @@ package cn.com.ctop.toutiao.modules.report.mapper;
 
 import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportMaterialDaily;
 import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportMaterialRetry;
+import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportVideoMaterialDaily;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -17,6 +18,8 @@ public interface BytedanceReportMaterialDailyMapper extends BaseMapper<Bytedance
 
     void replaceIntoBatch(@Param("infos") List<BytedanceReportMaterialDaily> infos);
 
+    void replaceIntoVideoMaterialBatch(@Param("infos") List<BytedanceReportVideoMaterialDaily> infos);
+
     void replaceMaterialRetry(@Param("retry") BytedanceReportMaterialRetry retry);
 
     List<BytedanceReportMaterialRetry> getRetryList();

+ 103 - 3
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/mapper/xml/BytedanceReportMaterialDailyMapper.xml

@@ -212,7 +212,8 @@
             start_date,
             end_date,
             status,
-            status_code
+            status_code,
+            type
         )
         VALUES
         (
@@ -220,7 +221,8 @@
             #{retry.startDate},
             #{retry.endDate},
             #{retry.status},
-            #{retry.statusCode}
+            #{retry.statusCode},
+            #{retry.type}
         )
 
     </insert>
@@ -230,7 +232,8 @@
             account_id,
             start_date,
             end_date,
-            status
+            status,
+            type
         from
         ctop_bytedance_report_material_retry
         where status = 0
@@ -246,4 +249,101 @@
         and start_date = #{retry.startDate}
         and end_date = #{retry.endDate}
     </update>
+
+    <insert id="replaceIntoVideoMaterialBatch">
+        REPLACE INTO ctop_bytedance_report_video_material_daily
+        (
+        account_id,
+        material_id,
+        stat_datetime,
+        click,
+        cost,
+        avg_click_cost,
+        deep_convert,
+        deep_convert_cost,
+        deep_convert_rate,
+        dislike,
+        report,
+        play_duration_2s_rate,
+        play_duration_3s_rate,
+        play_duration_5s_rate,
+        play_duration_10s_rate,
+        play_25_feed_break_rate,
+        play_50_feed_break_rate,
+        play_75_feed_break_rate,
+        play_100_feed_break_rate,
+        avg_show_cost,
+        total_play,
+        valid_play,
+        share_material,
+        comment_material,
+        follow,
+        valid_play_cost,
+        convert_material,
+        play_over_rate,
+        ctr,
+        like_material,
+        show_material,
+        convert_rate,
+        play_over,
+        message_action,
+        valid_play_rate,
+        average_play_time_per_play,
+        convert_cost,
+        convert_show_rate
+        )
+        VALUES
+        <foreach collection="infos" item="info" separator=",">
+            (
+            #{info.accountId},
+            #{info.materialId},
+            #{info.statDatetime},
+            #{info.click},
+            #{info.cost},
+            #{info.avgClickCost},
+            #{info.deepConvert},
+            #{info.deepConvertCost},
+            #{info.deepConvertRate},
+            #{info.dislike},
+            #{info.report},
+            #{info.playDuration2sRate},
+            #{info.playDuration3sRate},
+            #{info.playDuration5sRate},
+            #{info.playDuration10sRate},
+            #{info.play25FeedBreakRate},
+            #{info.play50FeedBreakRate},
+            #{info.play75FeedBreakRate},
+            #{info.play100FeedBreakRate},
+            #{info.avgShowCost},
+            #{info.totalPlay},
+            #{info.validPlay},
+            #{info.shareMaterial},
+            #{info.commentMaterial},
+            #{info.follow},
+            #{info.validPlayCost},
+            #{info.convertMaterial},
+            #{info.playOverRate},
+            #{info.ctr},
+            #{info.likeMaterial},
+            #{info.showMaterial},
+            #{info.convertRate},
+            #{info.playOver},
+            #{info.messageAction},
+            #{info.validPlayRate},
+            #{info.averagePlayTimePerPlay},
+            #{info.convertCost},
+            #{info.convertShowRate}
+            )
+        </foreach>
+    </insert>
+
+
+
+
+
+
+
+
+
+
 </mapper>

+ 3 - 1
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/IBytedanceReportService.java

@@ -39,7 +39,9 @@ public interface IBytedanceReportService {
 
     int bytedanceMaterialReport(CtopOauthToken token, String startDate, String endDate);
 
-    int bytedanceMaterialReportRetry(CtopOauthToken token, String startDate, String endDate);
+    int bytedanceMaterialReportRetry(Integer type, CtopOauthToken token, String startDate, String endDate);
 
     List<BytedanceReportMaterialRetry> getRetryList();
+
+    int bytedanceVideoMaterialReport(CtopOauthToken token, String startDate, String endDate);
 }

+ 122 - 14
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/BytedanceReportServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.ctop.common.module.utils.LoadFileUtil;
 import cn.com.ctop.toutiao.modules.report.entity.BytedanceDailyReportTask;
 import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportMaterialDaily;
 import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportMaterialRetry;
+import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportVideoMaterialDaily;
 import cn.com.ctop.toutiao.modules.report.mapper.BytedanceAdvertiserDailyReportMapper;
 import cn.com.ctop.toutiao.modules.report.mapper.BytedanceDailyReportTaskMapper;
 import cn.com.ctop.toutiao.modules.report.mapper.BytedanceReportMapper;
@@ -710,18 +711,25 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
     /////////////////////////////////////////////////////////\
     //素材报表
     @Override
-    public int bytedanceMaterialReportRetry(CtopOauthToken token, String startDate, String endDate) {
+    public int bytedanceMaterialReportRetry(Integer type, CtopOauthToken token, String startDate, String endDate) {
         Long accountId = token.getAccountId();
-        // log.info("头条素材报表当前accountId为:" + accountId);
+        log.info("头条素材报表重试开始 当前accountId:{}  {}~{},type:{}" , accountId, startDate,endDate,type);
         Integer page = 1;
         Integer pageSize = 100;
-        int code = bytedanceMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+        Integer code = null;
+        if(type == 1){
+            code = bytedanceMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+
+        }else if(type == 2){
+            code = bytedanceVideoMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+        }
 
         BytedanceReportMaterialRetry retry = new BytedanceReportMaterialRetry();
         retry.setAccountId(accountId);
         retry.setStartDate(startDate);
         retry.setEndDate(endDate);
         retry.setStatusCode(code);
+        retry.setType(type);
         if (code != 200 && code != 1) {
             retry.setStatus(0);
             bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
@@ -729,13 +737,14 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
             retry.setStatus(1);
             bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
         }
+        log.info("头条素材报表重试结束 当前accountId:{}  {}~{},type:{},code:{}" , accountId, startDate,endDate,type,code);
         return code;
     }
 
     @Override
     public int bytedanceMaterialReport(CtopOauthToken token, String startDate, String endDate) {
         Long accountId = token.getAccountId();
-        // log.info("头条素材报表当前accountId为:" + accountId);
+        log.info("头条素材报表开始 当前accountId:{}  {}~{}" , accountId, startDate,endDate);
         Integer page = 1;
         Integer pageSize = 100;
         int code = bytedanceMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
@@ -746,8 +755,10 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
             retry.setStartDate(startDate);
             retry.setEndDate(endDate);
             retry.setStatusCode(code);
+            retry.setType(1);
             bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
         }
+        log.info("头条素材报表结束 当前accountId为:{}  {}~{}" , accountId, startDate,endDate);
         return code;
     }
 
@@ -773,8 +784,7 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
 
         JSONObject json = HttpUtils.bytedanceGetRequest(access_token, open_api_domain + path, JSONObject.parseObject(JSONObject.toJSONString(data)));
         if (json == null) {
-            //insertMaterialRetry(accountId, startDate, endDate, -2);
-            log.error("请求有误:" + JSONObject.toJSONString(data));
+            log.error("返回为空,请求有误:" + JSONObject.toJSONString(data));
             return -2;
         }
 
@@ -783,13 +793,13 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
             if (!Check.isNull(json)) {
                 Integer code = json.getInteger("code");
                 if (code != 0) {
-                    log.error("获取任务列表返回信息错误,错误码为:" + code + ",头条accountId:" + accountId + ";返回json为:" + JSONObject.toJSONString(data));
+                    log.error("获取任务列表返回信息错误,错误码为:" + code + ",头条accountId:" + accountId + ";返回json为" + json + "请求为:" + JSONObject.toJSONString(data));
                     return -1;
                 }
 
                 JSONObject jsonData = json.getJSONObject("data");
                 if (Check.isNull(jsonData)) {
-                    log.error("获取任务列表返回信息data内容为空,头条accountId:" + accountId + ";返回json为:" + JSONObject.toJSONString(data));
+                    log.error("获取任务列表返回信息data内容为空,头条accountId:" + accountId + ";返回json为" + json + "请求为:" + JSONObject.toJSONString(data));
                     return -1;
                 }
                 JSONObject pageInfo = jsonData.getJSONObject("page_info");
@@ -799,7 +809,6 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                 JSONArray jsonArrayay = jsonData.getJSONArray("list");
                 if (jsonArrayay.size() == 0) {
                     log.info("accountId:" + accountId + ";没有数据。总页数为:" + totalPage + "当前页数为:" + currentPage);
-                    //returnCode = 1;
                     return 1;
                 }
 
@@ -911,19 +920,15 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
                         bytedanceReportMaterialDailyList.add(daily);
                     }
                 }
-                //Long insertStartTime = System.currentTimeMillis();
                 bytedanceReportMaterialDailyMapper.replaceIntoBatch(bytedanceReportMaterialDailyList);
-                //Long insertEndTime = System.currentTimeMillis();
-                //log.info("头条获取素材报表插入数据结束,执行耗时:{}秒", (insertEndTime - insertStartTime) / 1000);
                 if (currentPage >= totalPage) {
-                    //log.info("accountId:" + accountId + "数据同步完成,开始时间:" + startDate + ",结束时间:"+ endDate);
+                    log.info("头条素材报表当前accountId为:{}  {}~{},接口数据拉取成功" , accountId, startDate,endDate);
                     return 1;
                 } else {
                     int pageCode = bytedanceMaterialReportByPage(page + 1, pageSize, token, accountId, startDate, endDate);
                     return pageCode;
                 }
             } else {
-                //returnCode = -1;
                 log.error("服务器返回为空,json:" + JSONObject.toJSONString(data));
                 return -1;
             }
@@ -940,4 +945,107 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
         return bytedanceReportMaterialDailyMapper.getRetryList();
     }
 
+
+    /**
+     * 头条视频素材报表
+     * @param token
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    @Override
+    public int bytedanceVideoMaterialReport(CtopOauthToken token, String startDate, String endDate) {
+        Long accountId = token.getAccountId();
+        log.info("头条素材报表当前accountId为:{}  {}~{},开始" , accountId, startDate,endDate);
+        Integer page = 1;
+        Integer pageSize = 100;
+        int code = bytedanceVideoMaterialReportByPage(page, pageSize, token, accountId, startDate, endDate);
+        if (code != 200 && code != 1) {
+            BytedanceReportMaterialRetry retry = new BytedanceReportMaterialRetry();
+            retry.setAccountId(accountId);
+            retry.setStatus(0);
+            retry.setStartDate(startDate);
+            retry.setEndDate(endDate);
+            retry.setStatusCode(code);
+            retry.setType(2);  //1素材报表重试,2视频素材报表重试
+            bytedanceReportMaterialDailyMapper.replaceMaterialRetry(retry);
+        }
+        log.info("头条素材报表当前accountId为:{}  {}~{},结束" , accountId, startDate,endDate);
+        return code;
+    }
+
+    private int bytedanceVideoMaterialReportByPage(Integer page, Integer pageSize, CtopOauthToken token, Long accountId, String startDate, String endDate) {
+        log.info("当前页数:"+ page);
+        String access_token = token.getAccessToken();
+
+        // 请求地址
+        String open_api_domain = "https://ad.oceanengine.com";
+        String path = "/open_api/2/report/video/get/";
+
+        // 请求参数
+        Map data = new HashMap();
+        data.put("advertiser_id", accountId);
+        data.put("start_date", startDate);
+        data.put("end_date", endDate);
+        data.put("page", page);
+        data.put("page_size", pageSize);
+        data.put("group_by", new String[]{"STAT_GROUP_BY_MATERIAL_ID", "STAT_GROUP_BY_TIME_DAY"});
+
+        JSONObject json = HttpUtils.bytedanceGetRequest(access_token, open_api_domain + path, JSONObject.parseObject(JSONObject.toJSONString(data)));
+        if (json == null) {
+            log.error("返回为空,请求有误:" + JSONObject.toJSONString(data));
+            return -2;
+        }
+
+        int returnCode = 200;
+        try {
+            if (!Check.isNull(json)) {
+                Integer code = json.getInteger("code");
+                if (code != 0) {
+                    log.error("获取任务列表返回信息错误,错误码为:" + code + ",头条accountId:" + accountId + ";返回json为:" + json + "请求为:" + JSONObject.toJSONString(data));
+                    return -1;
+                }
+
+                JSONObject jsonData = json.getJSONObject("data");
+                if (Check.isNull(jsonData)) {
+                    log.error("获取任务列表返回信息data内容为空,头条accountId:" + accountId + ";返回json为:" + json + "请求为:" + JSONObject.toJSONString(data));
+                    return -1;
+                }
+                JSONObject pageInfo = jsonData.getJSONObject("page_info");
+                Integer totalPage = pageInfo.getInteger("total_page");
+                Integer currentPage = pageInfo.getInteger("page");
+
+                JSONArray jsonArrayay = jsonData.getJSONArray("list");
+                if (jsonArrayay.size() == 0) {
+                    log.info("accountId:" + accountId + ";没有数据。总页数为:" + totalPage + "当前页数为:" + currentPage);
+                    return 1;
+                }
+
+                List<BytedanceReportVideoMaterialDaily> bytedanceReportVideoMaterialDailyList = new ArrayList<>();
+                for (int i = 0; i < jsonArrayay.size(); i++) {
+                    JSONObject detailJson = jsonArrayay.getJSONObject(i);
+                    if (!Check.isNull(detailJson)) {
+                        BytedanceReportVideoMaterialDaily daily = new BytedanceReportVideoMaterialDaily(detailJson, accountId);
+                        bytedanceReportVideoMaterialDailyList.add(daily);
+                    }
+                }
+                bytedanceReportMaterialDailyMapper.replaceIntoVideoMaterialBatch(bytedanceReportVideoMaterialDailyList);
+                if (currentPage >= totalPage) {
+                    log.info("头条视频素材报表当前accountId为:{}  {}~{},接口数据拉取成功" , accountId, startDate,endDate);
+                    return 1;
+                } else {
+                    return bytedanceVideoMaterialReportByPage(page + 1, pageSize, token, accountId, startDate, endDate);
+                }
+            } else {
+                log.error("头条视频素材报表服务器返回为空,accountId:" + accountId + ",json:" + json + "请求为:" + JSONObject.toJSONString(data));
+                return -1;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("头条视频素材报表其他错误,accountId:" + accountId + ",json:" + json + "请求为:" + JSONObject.toJSONString(data));
+            returnCode = -3;
+        }
+        return returnCode;
+    }
+
 }