Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

ZHAOXIAN 1 год назад
Родитель
Сommit
4816ecc294
44 измененных файлов с 1744 добавлено и 69 удалено
  1. 5 0
      job-bytedance/pom.xml
  2. 62 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/DianZhongConfig.java
  3. 61 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/RestTemplateConfig.java
  4. 24 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/BytedanceController.java
  5. 51 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/DianZhongController.java
  6. 19 1
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/FeishuController.java
  7. 17 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/BytedanceErrorLog.java
  8. 17 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/CsjAlbumResourceInfo.java
  9. 22 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/CsjAlbumSeqResourceInfo.java
  10. 5 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/BytedanceMiniAppMapper.java
  11. 19 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/CsjResourceMapper.java
  12. 16 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/DianZhongMapper.java
  13. 19 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceMiniAppMapper.xml
  14. 9 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceProductReportMapper.xml
  15. 7 6
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceProductUpdateMapper.xml
  16. 50 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/CsjResourceMapper.xml
  17. 37 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/DianZhongMapper.xml
  18. 47 37
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/ReportsAdPushMapper.xml
  19. 6 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IBytedanceMaterialReportService.java
  20. 2 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IBytedanceMiniAppService.java
  21. 12 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/ICsjResourceService.java
  22. 12 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IDianZhongService.java
  23. 4 1
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/AdminAdvertiserListServiceImpl.java
  24. 61 2
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceCdpProjectServiceImpl.java
  25. 112 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceMaterialReportServiceImpl.java
  26. 57 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceMiniAppServiceImpl.java
  27. 27 7
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceProductUpdateServiceImpl.java
  28. 169 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/CsjResourceServiceImpl.java
  29. 2 1
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/DateReportsPushServiceImpl.java
  30. 293 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/DianZhongServiceImpl.java
  31. 6 5
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/ReportsAdPushServiceImpl.java
  32. 2 1
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/ReportsByBusinessPushServiceImpl.java
  33. 75 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/utils/DateUtils.java
  34. 42 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/utils/FieldsConfig.java
  35. 1 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AdminAdvertiserListJob.java
  36. 8 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMiniAppJob.java
  37. 23 7
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedancePromoterReportJob.java
  38. 46 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceReportRetryJob.java
  39. 80 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/CsjResoureJob.java
  40. 55 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/DianZhongJob.java
  41. 24 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/OssProperties.java
  42. 108 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/OssUtil.java
  43. 11 1
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/doris/sink/DorisMultiTableStreamLoadManager.java
  44. 19 0
      job-bytedance/src/main/resources/application.yml

+ 5 - 0
job-bytedance/pom.xml

@@ -187,6 +187,11 @@
             <artifactId>commons-pool2</artifactId>
             <version>2.6.2</version>
         </dependency>
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.16.0</version>
+        </dependency>
 
     </dependencies>
     <build>

+ 62 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/DianZhongConfig.java

@@ -0,0 +1,62 @@
+package cn.com.ctop.job.bytedance.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Configuration
+@ConfigurationProperties(prefix = "dianzhong.client")
+public class DianZhongConfig {
+    private static List<DZConfig> dzConfig;
+    private static final Map<String, String> tokenMap = new ConcurrentHashMap<>();
+
+    public List<DZConfig> getDzConfig() {
+        return dzConfig;
+    }
+
+    public String getToken(String clientId) {
+        if (tokenMap.isEmpty()) {
+            for (DZConfig config : dzConfig) {
+                tokenMap.put(config.getClientId(), config.getToken());
+            }
+        }
+        return tokenMap.get(clientId);
+    }
+
+    public void setDzConfig(List<DZConfig> dzConfig) {
+        DianZhongConfig.dzConfig = dzConfig;
+    }
+
+    public static class DZConfig {
+        private String clientId;
+        private String token;
+        private String type;
+
+        public String getClientId() {
+            return clientId;
+        }
+
+        public void setClientId(String clientId) {
+            this.clientId = clientId;
+        }
+
+        public String getToken() {
+            return token;
+        }
+
+        public void setToken(String token) {
+            this.token = token;
+        }
+
+        public String getType() {
+            return type;
+        }
+
+        public void setType(String type) {
+            this.type = type;
+        }
+    }
+}

+ 61 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/RestTemplateConfig.java

@@ -0,0 +1,61 @@
+package cn.com.ctop.job.bytedance.config;
+
+import org.apache.http.NoHttpResponseException;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.protocol.HttpContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class RestTemplateConfig {
+
+
+    @Bean(name = "downloadFileRestTemplate")
+    public RestTemplate restTemplate(){
+        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
+        httpRequestFactory.setConnectionRequestTimeout(50000);
+        httpRequestFactory.setConnectTimeout(5000);
+        httpRequestFactory.setReadTimeout(300000);
+
+        CloseableHttpClient httpClient = HttpClientBuilder.create()
+                .setConnectionTimeToLive(300, TimeUnit.SECONDS)
+                .setRetryHandler(new HttpRequestRetryHandler() {
+                    @Override
+                    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
+                        if (executionCount >= 3) {
+                            // 最多重试3次
+                            return false;
+                        } else if (exception instanceof NoHttpResponseException) {
+                            // 对于服务器未响应的情况进行重试
+                            requestWait();
+                            return true;
+                        } else if (exception instanceof InterruptedIOException) {
+                            // 对于连接中断的情况进行重试
+                            requestWait();
+                            return true;
+                        }
+                        return false;
+                    }
+                }).build();
+
+        httpRequestFactory.setHttpClient(httpClient);
+
+        return new RestTemplate(httpRequestFactory);
+    }
+
+    public void requestWait() {
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 24 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/BytedanceController.java

@@ -50,6 +50,9 @@ public class BytedanceController {
     @Autowired
     private IBytedanceCdpProjectService cdpProjectService;
 
+    @Autowired
+    private IBytedanceMaterialReportService bytedanceMaterialReportService;
+
 
     @GetMapping("/accountReport")
     public void getChannel() {
@@ -116,6 +119,14 @@ public class BytedanceController {
         }
     }
 
+    @GetMapping("/miniAppAdPlacement")
+    public void miniAppAdPlacement() throws Exception {
+        List<String> appIds = bytedanceMiniAppService.getAllAppIds();
+        for (String appId : appIds) {
+            bytedanceMiniAppService.getAdPlacement(appId);
+        }
+    }
+
     @GetMapping("/flowDetailsReport")
     public void flowDetailsReport(@RequestParam(required = false) Long advertiserId, String accessToken, String startDate, String endDate) {
 
@@ -219,4 +230,17 @@ public class BytedanceController {
     public void bytedanceAccountHour(Long advertiserId, String accessToken, String date) {
         accountReportService.getBytedanceAccountHour(advertiserId, accessToken, date, date, 1, 0);
     }
+
+    @GetMapping("/materialDaily")
+    public void materialDaily(@RequestParam(required = false) Long advertiserId, String startDate, String endDate) {
+        List<JSONObject> costAccount = productReportService.getCostAccount(advertiserId, startDate, endDate);
+        for (JSONObject jsonObject : costAccount) {
+            dailyRetrExecutorService.submit(() -> {
+                Long adverId = jsonObject.getLong("advertiserId");
+                String accessToken = jsonObject.getString("accessToken");
+                bytedanceMaterialReportService.getBytedanceMaterialDailyReport(adverId, accessToken, startDate, endDate, 1, null, 1, 0);
+            });
+        }
+    }
+
 }

+ 51 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/DianZhongController.java

@@ -0,0 +1,51 @@
+package cn.com.ctop.job.bytedance.controller;
+
+import cn.com.ctop.job.bytedance.config.DianZhongConfig;
+import cn.com.ctop.job.bytedance.data.service.IDianZhongService;
+import cn.com.ctop.job.bytedance.data.utils.DateUtils;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@RestController
+@RequestMapping("/bytedance/dianzhong")
+@Api(tags = "点众拉取")
+@Slf4j
+public class DianZhongController {
+    @Autowired
+    private IDianZhongService dianZhongService;
+
+    @Resource
+    private DianZhongConfig dianZhongConfig;
+
+
+    @GetMapping("/getDownloadUrl")
+    public void downloadUrl(String type,
+                            @RequestParam(required = false) String statDate,
+                            @RequestParam(required = false, defaultValue = "false") Boolean allDay) {
+        List<DianZhongConfig.DZConfig> dzConfig = dianZhongConfig.getDzConfig();
+        for (DianZhongConfig.DZConfig config : dzConfig) {
+            if ("iaa".equals(config.getType())) {
+                continue;
+            }
+            String clientId = config.getClientId();
+            String token = config.getToken();
+            String queryStartTime = DateUtils.getQueryStartTime(statDate, "yyyy-MM-dd HH:mm:ss", allDay);
+            String queryEndTime = DateUtils.getQueryEndTime(statDate, "yyyy-MM-dd HH:mm:ss", allDay);
+            dianZhongService.getDownloadUrl(type, clientId, token, queryStartTime, queryEndTime, null, false);
+        }
+    }
+
+    @GetMapping("/getUrlData")
+    public void urlData(String statDate) {
+        dianZhongService.getUrlData(statDate);
+    }
+
+}

+ 19 - 1
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/FeishuController.java

@@ -1,6 +1,8 @@
 package cn.com.ctop.job.bytedance.controller;
 
 import cn.com.ctop.job.bytedance.data.service.*;
+import cn.com.ctop.job.bytedance.handler.CsjResoureJob;
+import cn.com.ctop.job.bytedance.utils.OssUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import io.swagger.annotations.Api;
@@ -28,14 +30,30 @@ public class FeishuController {
     IBindAppErrorWarnService bindAppErrorWarnService;
     @Autowired
     IBytedanceProductUpdateService bytedanceProductUpdateService;
+    @Autowired
+    IReportsByBusinessPushService reportsByBusinessPushService;
+    @Autowired
+    ICutGroupRankPushService cutGroupRankPushService;
+    @Autowired
+    OssUtil ossUtil;
+    @Autowired
+    CsjResoureJob csjResoureJob;
 
     @Autowired
     IUserLoginRecordService userLoginRecordService;
     @GetMapping("/test")
     public void test() throws Exception {
 //        bytedanceProductUpdateService.initNew();
-        bytedanceProductUpdateService.run();
+//        bytedanceProductUpdateService.run();
+//        reportsAdPushService.test();
+//        totalRankPushService.test();
+//        dateReportsPushService.preSend();
+//        optimizerRankPushService.send();
+//        unbindWarnPushService.send();
+//        cutGroupRankPushService.send();
+//        reportsByBusinessPushService.test();
 
+        csjResoureJob.csjResourceOssJob();
     }
 
 

+ 17 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/BytedanceErrorLog.java

@@ -1,12 +1,15 @@
 package cn.com.ctop.job.bytedance.data.entity;
 
 
+import lombok.Builder;
+
 /**
  * 头条报错误日志对象 bytedance_error_log
  *
  * @author ruoyi
  * @date 2025-03-07
  */
+@Builder
 public class BytedanceErrorLog {
     private static final long serialVersionUID = 1L;
 
@@ -42,6 +45,20 @@ public class BytedanceErrorLog {
     private Integer isSend;
     private String msg;
 
+    public BytedanceErrorLog() {
+    }
+
+    public BytedanceErrorLog(Long id, Long advertiserId, String startDate, String endDate, String dataDimension, String dataType, Integer isSend, String msg) {
+        this.id = id;
+        this.advertiserId = advertiserId;
+        this.startDate = startDate;
+        this.endDate = endDate;
+        this.dataDimension = dataDimension;
+        this.dataType = dataType;
+        this.isSend = isSend;
+        this.msg = msg;
+    }
+
     public Long getId() {
         return id;
     }

+ 17 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/CsjAlbumResourceInfo.java

@@ -0,0 +1,17 @@
+package cn.com.ctop.job.bytedance.data.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class CsjAlbumResourceInfo {
+
+    private String resourceId;
+
+    private String albumId;
+
+    private String ossCoverImg;
+    //每个剧集的信息
+    private List<CsjAlbumSeqResourceInfo> seqList;
+}

+ 22 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/CsjAlbumSeqResourceInfo.java

@@ -0,0 +1,22 @@
+package cn.com.ctop.job.bytedance.data.entity;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@Data
+public class CsjAlbumSeqResourceInfo {
+
+    private String albumId;
+    //第几集
+    private Integer seq;
+    //本集oss封面图
+    private String ossSeqImg;
+    //本集oss视频链接
+    private String ossSeqVideo;
+
+    public CsjAlbumSeqResourceInfo(String albumId, Integer seq) {
+        this.albumId = albumId;
+        this.seq = seq;
+    }
+}

+ 5 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/BytedanceMiniAppMapper.java

@@ -3,6 +3,7 @@ package cn.com.ctop.job.bytedance.data.mapper;
 import cn.com.ctop.job.bytedance.data.entity.BytedanceAdvertiserReportDaily;
 import cn.com.ctop.job.bytedance.data.entity.BytedanceAdvertiserReportHour;
 import cn.com.ctop.job.bytedance.data.entity.BytedanceErrorLog;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.dynamic.datasource.annotation.DS;
 import org.apache.ibatis.annotations.Param;
@@ -18,5 +19,9 @@ public interface BytedanceMiniAppMapper {
 
     List<String> getIaaAppIds();
 
+    List<String> getAllAppIds();
+
     List<JSONObject> getMaEcpmRetryJob();
+
+    void insertAdPlacement(@Param("list")JSONArray result);
 }

+ 19 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/CsjResourceMapper.java

@@ -0,0 +1,19 @@
+package cn.com.ctop.job.bytedance.data.mapper;
+
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumResourceInfo;
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumSeqResourceInfo;
+
+import java.util.List;
+
+public interface CsjResourceMapper {
+
+    List<CsjAlbumResourceInfo> getResources();
+
+    String getToken();
+
+    int updateAlbum(CsjAlbumResourceInfo album);
+
+    int updateSeq(CsjAlbumSeqResourceInfo albumSeq);
+
+    int batchUpdateAlbumSeq(List<CsjAlbumSeqResourceInfo> list);
+}

+ 16 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/DianZhongMapper.java

@@ -0,0 +1,16 @@
+package cn.com.ctop.job.bytedance.data.mapper;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface DianZhongMapper {
+    void insertDownloadTask(@Param("item") JSONObject jsonObject);
+
+    List<JSONObject> getDZRetry();
+
+    List<JSONObject> getTaskUrl(@Param("statDate") String statDate);
+
+    void updateTaskDownloaded(@Param("taskId") String taskId);
+}

+ 19 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceMiniAppMapper.xml

@@ -1,12 +1,31 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="cn.com.ctop.job.bytedance.data.mapper.BytedanceMiniAppMapper">
+    <insert id="insertAdPlacement">
+        replace into media_api.bytedance_ad_placement_list
+                (app_id,ad_placement_id,ad_placement_name,ad_placement_type,ad_placement_type_name,status)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.app_id},
+            #{item.ad_placement_id},
+            #{item.ad_placement_name},
+            #{item.ad_placement_type},
+            #{item.ad_placement_type_name},
+            #{item.status}
+            )
+        </foreach>
+    </insert>
     <select id="getEcpmKeys" resultType="java.lang.String">
         SELECT concat(event_timestamp,open_id,cost) as ecpm_keys from media_api.bytedance_webhook_ma_ecpm
         where stat_date >=  #{startDate} and stat_date &lt;= #{endDate}
           and event_time >= #{startTime} and event_time &lt;= #{endTime}
     </select>
 
+    <select id="getAllAppIds" resultType="java.lang.String">
+        select app_id from deepthink.mini_app_info where app_id like 'tt%'
+    </select>
+
     <select id="getIaaAppIds" resultType="java.lang.String">
         select app_id from deepthink.mini_app_info where business_method in('IAA','MIX') and app_id like 'tt%'
     </select>

+ 9 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceProductReportMapper.xml

@@ -10,6 +10,15 @@
                 and advertiser_id = ${advertiserId}
             </if>
             group by 1
+
+            union
+
+            select advertiser_id from media_api.bytedance_promoter_report_daily
+            where stat_time_day >= ${startDate} and stat_time_day &lt;= ${endDate}
+            <if test="advertiserId != null">
+                and advertiser_id = ${advertiserId}
+            </if>
+            group by 1
         ) t1
         LEFT JOIN tidb.deepthink.bytedance_advertiser_list t2 ON t1.advertiser_id = t2.advertiser_id
         LEFT JOIN tidb.deepthink.bytedance_auth_list t3 ON t2.admin_advertiser_id = t3.admin_advertiser_id

+ 7 - 6
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceProductUpdateMapper.xml

@@ -29,21 +29,21 @@
         FROM deepthink.bytedance_product_main_advertiser t1
         left join deepthink.bytedance_advertiser_list t2 on t1.advertiser_id=t2.advertiser_id
         left join deepthink.bytedance_auth_list t3 on t2.admin_advertiser_id=t3.admin_advertiser_id
-        where t1.`type`=2 and t1.`_status`=0 and platform_type=1 and tb1.mini_instance_id is not null
+        where t1.`type`=2 and t1.`_status`=0 and platform_type=1 and t1.mini_instance_id is not null
     </select>
     <select id="getIAAPlatformList" resultType="com.alibaba.fastjson.JSONObject">
         select t1.*, t3.access_token
         FROM deepthink.bytedance_product_main_advertiser t1
         left join deepthink.bytedance_advertiser_list t2 on t1.advertiser_id=t2.advertiser_id
         left join deepthink.bytedance_auth_list t3 on t2.admin_advertiser_id=t3.admin_advertiser_id
-        where t1.`type`=1 and t1.`_status`=0 and platform_type=1 and tb1.mini_instance_id is not null
+        where t1.`type`=1 and t1.`_status`=0 and platform_type=1 and t1.mini_instance_id is not null
     </select>
     <select id="getIAPVideoList" resultType="com.alibaba.fastjson.JSONObject">
         select third.album_id, third.platform_type, detail.platform_config, video.id as video_id, detail.id as video_detail_id, video.name as name, video.cover_img as img,ifnull(category.name, '其他') as 'theme', video.play_platform,
         '天津星链视界信息技术有限公司' as copyright_owner, '其他' as playlet_gender, video.update_sort as playlet_num, '2' as playlet_duration,
-        payinfo.sort as start_pay_playlet, '5' as membership_types, '1' as has_paid_content, '2' as has_motivation_types,
+        payinfo.sort as start_pay_playlet, '5' as membership_types, '2' as has_motivation_types,
         payinfo.maxpay as max_charge, payinfo.minpay as min_charge, maxpay as recommended_charge, maxpay as price,
-        2 as has_paid_content, 1 as has_motivation_content
+         1 as has_motivation_content
         FROM (select video_id, album_id, 1 as platform_type from thirtpart.ly_third_videos where submission_status=2 and platform=2
         and video_id in (select video_id from thirtpart.ly_video_audit_records where audit_status=2)
         union select ly_video_id as video_id, album_id, 2 as platform_type from deepthink.bytedance_upload_album where can_promotion=1
@@ -52,7 +52,8 @@
         LEFT JOIN (select * from thirtpart.ly_videos) video ON third.video_id = video.id
         LEFT JOIN thirtpart.ly_video_category category ON video.category_id = category.id
         LEFT JOIN (select video_id, min(sort) as sort, max(pay_amount/100.0) as maxpay, min(pay_amount/100.0) as minpay from thirtpart.ly_video_details where is_pay=1 group by video_id) payinfo ON video.id = payinfo.video_id
-        where video.is_free = 1 or (payinfo.sort is not null and maxpay>0)
+        where (video.is_free = 1 or (payinfo.sort is not null and maxpay>0))
+        and video.source=1 and video.created_at > unix_timestamp(date_sub(now(), interval 7 day))
     </select>
     <select id="getIAAVideoList" resultType="com.alibaba.fastjson.JSONObject">
         select third.album_id, third.platform_type, detail.platform_config, video.id as video_id, detail.id as video_detail_id, video.name as name, video.cover_img as img,ifnull(category.name, '其他') as 'theme', video.play_platform,
@@ -66,7 +67,7 @@
         LEFT JOIN (select * from thirtpart.ly_videos where play_platform like '%2%') video ON third.video_id = video.id
         LEFT JOIN thirtpart.ly_video_category category ON video.category_id = category.id
         LEFT JOIN (select video_id, max(sort) as sort from thirtpart.ly_video_details where is_pay=0 group by video_id) payinfo ON video.id = payinfo.video_id
-        where video.is_free = 0
+        where video.is_free = 0 and video_source=1
     </select>
     <select id="getIAPProductTypeEnums" resultType="com.alibaba.fastjson.JSONObject">
         select first_type_name, first_type_id, second_type_name, second_type_id, third_type_name, third_type_id

+ 50 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/CsjResourceMapper.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.com.ctop.job.bytedance.data.mapper.CsjResourceMapper">
+
+    <resultMap id="albumInfo" type="cn.com.ctop.job.bytedance.data.entity.CsjAlbumResourceInfo">
+        <id property="albumId" column="album_id"/>
+        <result property="resourceId" column="resource_id"/>
+        <result property="ossCoverImg" column="oss_cover_img"/>
+        <collection property="seqList" ofType="cn.com.ctop.job.bytedance.data.entity.CsjAlbumSeqResourceInfo">
+            <result property="ossSeqImg" column="seq_img"/>
+            <result property="ossSeqVideo" column="seq_video"/>
+            <result property="seq" column="seq"/>
+            <result property="albumId" column="album_id"/>
+        </collection>
+    </resultMap>
+    <update id="updateAlbum">
+        replace INTO thirtpart.csj_album_resource_info
+        (album_id, oss_cover_img)
+        VALUES
+        (#{albumId}, #{ossCoverImg})
+    </update>
+    <update id="batchUpdateAlbumSeq">
+        replace INTO thirtpart.csj_album_seq_resource_info
+        (album_id, seq, oss_cover_img, oss_video_url)
+        VALUES
+        <foreach collection="list" item="item" separator=",">
+            (#{item.albumId}, #{item.seq}, #{item.ossSeqImg}, #{item.ossSeqVideo})
+        </foreach>
+    </update>
+    <update id="updateSeq">
+        replace INTO thirtpart.csj_album_seq_resource_info
+        (album_id, seq, oss_cover_img, oss_video_url)
+        VALUES
+        (#{albumId}, #{seq}, #{ossSeqImg}, #{ossSeqVideo})
+    </update>
+
+    <select id="getResources" resultMap="albumInfo">
+        SELECT tb1.album_id, tb0.resource_id, tb2.oss_cover_img, tb3.seq, tb3.oss_cover_img as seq_img, tb3.oss_video_url as seq_video
+        FROM
+        thirtpart.csj_authorization_list_use tb0
+        LEFT JOIN thirtpart.csj_authorization_detail tb1 on tb0.resource_id = tb1.resource_id
+        LEFT JOIN thirtpart.csj_album_resource_info tb2 on tb1.album_id = tb2.album_id
+        LEFT JOIN thirtpart.csj_album_seq_resource_info tb3 on tb1.album_id = tb3.album_id
+        WHERE tb1.album_id is not null
+        ORDER BY tb1.create_time DESC
+    </select>
+    <select id="getToken" resultType="java.lang.String">
+        select authorizer_access_token from thirtpart.thirt_app_token where auth_app_id='ttdf35a988403ffce301'
+    </select>
+</mapper>

+ 37 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/DianZhongMapper.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="cn.com.ctop.job.bytedance.data.mapper.DianZhongMapper">
+
+    <insert id="insertDownloadTask">
+        insert into media_api.dianzhong_data_download_url
+        (stat_date,task_id,`type`,client_id,start_time,end_time) values
+        (
+        #{item.stat_date},
+        #{item.task_id},
+        #{item.type},
+        #{item.client_id},
+        #{item.start_time},
+        #{item.end_time}
+        )
+        on duplicate key update
+        stat_date= VALUES(stat_date),`type`= VALUES(`type`),client_id= VALUES(client_id),
+        start_time= VALUES(start_time),end_time= VALUES(end_time)
+    </insert>
+    <update id="updateTaskDownloaded">
+        update media_api.dianzhong_data_download_url
+        set downloaded = 1 where task_id = #{taskId}
+    </update>
+
+    <select id="getTaskUrl" resultType="com.alibaba.fastjson.JSONObject">
+        select task_id,url,type,client_id
+        from media_api.dianzhong_data_download_url
+        where stat_date= ${statDate} and downloaded = 0 and url is not null and url != '-1'
+    </select>
+
+    <select id="getDZRetry" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT t1.is_send AS 'isSend', t1.id AS 'id', t1.advertiser_id AS 'advertiserId', t1.start_date AS 'startDate', t1.end_date AS 'endDate', t1.data_dimension AS 'dataDimension', t1.data_type AS 'dataType', t3.access_token AS 'accessToken'
+        FROM bytedance_error_log t1
+        where data_dimension like 'dianzhong%'
+    </select>
+
+</mapper>

+ 47 - 37
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/ReportsAdPushMapper.xml

@@ -42,10 +42,17 @@
     <sql id="realCostAmount">
         round(ifnull(sum(real_cost_amount), 0), 2) as real_cost_amount
     </sql>
+    <sql id="iaaRoi">
+        concat(round(if(ifnull(sum(iaa_real_cost_amount),0)=0, 0, ifnull(sum(share_iaa_amount_3), 0)/sum(iaa_real_cost_amount)*100), 2), '%') AS iaa_roi
+    </sql>
+    <sql id="iapRoi">
+        concat(round(if(ifnull(sum(iap_real_cost_amount),0)=0, 0, ifnull(sum(share_pay_amount), 0)/sum(iap_real_cost_amount)*100), 2), '%') AS iap_roi
+    </sql>
 
     <select id="tmpPushData" resultType="java.util.Map">
         select
         <include refid="costAmount"/>,
+        <include refid="realCostAmount"/>,
         <include refid="payAmount"/>,
         <include refid="shareIaaAmount"/>,
         <include refid="realProfit"/>,
@@ -53,7 +60,7 @@
         FROM
             (select sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount, max(update_time) as update_time
              from application.media_ad_report_daily
-             where stat_date = ${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+             where stat_date = ${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
             ) tb1,
             (select sum(pay_amount) as pay_amount,
                     sum(iaa_amount) as iaa_amount,
@@ -61,12 +68,13 @@
                     sum(share_pay_amount) as share_pay_amount,
                     sum(share_iaa_amount) as share_iaa_amount
              from application.user_data_report_daily
-             where stat_date = ${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+             where stat_date = ${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
             ) tb2
     </select>
     <select id="adHourData" resultType="java.util.Map">
         select
         <include refid="costAmount"/>,
+        <include refid="realCostAmount"/>,
         <include refid="payAmount"/>,
         <include refid="shareIaaAmount"/>,
         <include refid="realProfit"/>,
@@ -75,13 +83,13 @@
         from
         (select sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount
         from application.media_ad_report_hourly
-        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         ) tb1,
         (select sum(pay_amount) as pay_amount, sum(iaa_amount) as iaa_amount,
         sum(share_iaa_amount_3) as share_iaa_amount_3,
         sum(share_iaa_amount) as share_iaa_amount, sum(share_pay_amount) as share_pay_amount
         from application.user_data_report_hourly
-        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         ) tb2
     </select>
     <select id="tmpTopMovie" resultType="java.util.Map">
@@ -91,11 +99,11 @@
         <include refid="endAmount"/>,
         <include refid="costAmount"/>,
         <include refid="realCostAmount"/>,
-        concat(round(if(ifnull(sum(iaa_real_cost_amount),0)=0, 0, sum(share_iaa_amount_3)/sum(iaa_real_cost_amount)*100), 2), '%') AS iaa_roi,
-        concat(round(if(ifnull(sum(iap_real_cost_amount),0)=0, 0, sum(share_pay_amount)/sum(iap_real_cost_amount)*100), 2), '%') AS iap_roi
+        <include refid="iaaRoi"/>,
+        <include refid="iapRoi"/>
         from
-        (select product_id from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
-        union select movie_id from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        (select product_id from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
+        union select movie_id from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         ) tb1
         left join
         (select product_id, sum(iaa_cost_amount) as iaa_cost_amount, sum(iaa_real_cost_amount) as iaa_real_cost_amount,
@@ -104,12 +112,12 @@
         sum(iaa_real_cost_amount)+sum(iap_real_cost_amount) as real_cost_amount
         from
         (select product_id, round(ifnull(sum(cost_amount),0),2) as iaa_cost_amount, sum(real_cost_amount) as iaa_real_cost_amount, 0 as iap_cost_amount, 0 as iap_real_cost_amount
-        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAA')
+        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAA')
         group by product_id
         union all
         select product_id, 0 as iaa_cost_amount, 0 as iaa_real_cost_amount,
         round(ifnull(sum(cost_amount),0),2) as cost_amount, sum(real_cost_amount) as real_cost_amount
-        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAP')
+        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAP')
         group by product_id) subt2
         group by product_id
         ) tb2 on tb1.product_id=tb2.product_id
@@ -119,7 +127,7 @@
         ifnull(sum(share_pay_amount), 0) as share_pay_amount,
         ifnull(sum(share_iaa_amount), 0) as share_iaa_amount,
         round(ifnull(sum(share_iaa_amount_3), 0),2) as share_iaa_amount_3
-        from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by movie_id
         ) tb3 on tb1.product_id=tb3.movie_id
         left join
@@ -134,6 +142,7 @@
     <select id="adDailyData" resultType="java.util.Map">
         select
         <include refid="costAmount"/>,
+        <include refid="realCostAmount"/>,
         <include refid="payAmount"/>,
         <include refid="shareIaaAmount"/>,
         <include refid="realProfit"/>,
@@ -143,13 +152,13 @@
         from
         (select sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount, max(update_time) as update_time
         from application.media_ad_report_daily
-        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         ) tb1,
         (select sum(pay_amount) as pay_amount, sum(iaa_amount) as iaa_amount,
         sum(share_iaa_amount) as share_iaa_amount, sum(share_pay_amount) as share_pay_amount,
         sum(share_iaa_amount_3) as share_iaa_amount_3
         from application.user_data_report_daily
-        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         ) tb2
     </select>
 
@@ -161,12 +170,12 @@
         <include refid="waterEndAmount"/>,
         <include refid="costAmount"/>,
         <include refid="realCostAmount"/>,
-        concat(round(if(ifnull(sum(iaa_real_cost_amount),0)=0, 0, sum(share_iaa_amount_3)/sum(iaa_real_cost_amount)*100), 2), '%') AS iaa_roi,
-        concat(round(if(ifnull(sum(iap_real_cost_amount),0)=0, 0, sum(share_pay_amount)/sum(iap_real_cost_amount)*100), 2), '%') AS iap_roi,
+        <include refid="iaaRoi"/>,
+        <include refid="iapRoi"/>,
         round(ifnull(sum(hour_cost_amount), 0), 2) as hour_cost_amount
         from
-        (select product_id from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
-        union select movie_id from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))) tb1
+        (select product_id from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
+        union select movie_id from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))) tb1
         left join
         (
         select product_id, sum(iaa_cost_amount) as iaa_cost_amount, sum(iaa_real_cost_amount) as iaa_real_cost_amount,
@@ -175,11 +184,11 @@
         sum(iaa_real_cost_amount)+sum(iap_real_cost_amount) as real_cost_amount
         from
         (select product_id, round(ifnull(sum(cost_amount),0),2) as iaa_cost_amount, sum(real_cost_amount) as iaa_real_cost_amount, 0 as iap_cost_amount, 0 as iap_real_cost_amount
-        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAA')
+        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAA')
         group by product_id
         union all
         select product_id, 0 as iaa_cost_amount, 0 as iaa_real_cost_amount,round(ifnull(sum(cost_amount),0),2) as cost_amount, sum(real_cost_amount) as real_cost_amount
-        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAP')
+        from application.media_product_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAP')
         group by product_id) subt2
         group by product_id
         ) tb2 on tb1.product_id=tb2.product_id
@@ -188,7 +197,7 @@
         sum(share_iaa_amount_3) as share_iaa_amount_3,
         ifnull(sum(share_iaa_amount), 0) as share_iaa_amount,
         ifnull(sum(share_pay_amount), 0) as share_pay_amount
-        from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by movie_id
         ) tb3 on tb1.product_id=tb3.movie_id
         left join
@@ -196,7 +205,7 @@
         ) tb4 on tb1.product_id=tb4.moive_id
         left join
         (select product_id, ifnull(sum(cost_amount), 0) as hour_cost_amount from application.media_product_report_hourly
-        where stat_date=${date} and `hour`=${hour}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date=${date} and `hour`=${hour}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by product_id) tb5 on tb1.product_id=tb5.product_id
         where 1=1 and tb1.product_id != '-9999'
         group by tb4.standard_movie_name
@@ -209,8 +218,8 @@
         select tb1.user_id, tb4.phonenumber, tb4.nick_name, tb4.dept_id, tb5.dept_name,
         rank() over (order by sum(cost_amount) desc) as rk,
         <include refid="costAmount"/>,
-        concat(round(if(ifnull(sum(iaa_real_cost_amount),0)=0, 0, sum(share_iaa_amount_3)/sum(iaa_real_cost_amount)*100), 2), '%') AS iaa_roi,
-        concat(round(if(ifnull(sum(iap_real_cost_amount),0)=0, 0, sum(share_pay_amount)/sum(iap_real_cost_amount)*100), 2), '%') AS iap_roi
+        <include refid="iaaRoi"/>,
+        <include refid="iapRoi"/>
         from
         (select cast(advertiser_id as char) advertiser_id, user_id from tidb.deepthink.advertiser_bind_info) tb1
         left join
@@ -220,11 +229,11 @@
         sum(iaa_real_cost_amount)+sum(iap_real_cost_amount) as real_cost_amount
         FROM
         (select advertiser_id, round(ifnull(sum(cost_amount),0),2) as iaa_cost_amount, sum(real_cost_amount) as iaa_real_cost_amount, 0 as iap_cost_amount, 0 as iap_real_cost_amount
-        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAA')
+        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAA')
         group by advertiser_id
         UNION ALL
         select advertiser_id, 0 as iaa_cost_amount, 0 as iaa_real_cost_amount,round(ifnull(sum(cost_amount),0),2) as iap_cost_amount, sum(real_cost_amount) as iap_real_cost_amount
-        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAP')
+        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAP')
         group by advertiser_id)subtb2
         group by advertiser_id
         ) tb2
@@ -233,7 +242,7 @@
         round(ifnull(sum(share_iaa_amount_3), 0),2) as share_iaa_amount_3,
         sum(share_iaa_amount) as share_iaa_amount,
         sum(share_pay_amount) as share_pay_amount
-        from application.user_data_report_daily where stat_date=${date}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        from application.user_data_report_daily where stat_date=${date}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb3
         on tb1.advertiser_id = tb3.advertiser_id
         left join (select user_id, nick_name, phonenumber, dept_id from tidb.deepthink.sys_user) tb4
@@ -256,13 +265,13 @@
         left join
         (select advertiser_id, sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount, max(update_time) as update_time
         from application.media_ad_report_daily
-        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb2 on tb1.advertiser_id = tb2.advertiser_id
         left join
         (select advertiser_id, sum(pay_amount) as pay_amount, sum(iaa_amount) as iaa_amount,
         sum(share_iaa_amount) as share_iaa_amount, sum(share_pay_amount) as share_pay_amount
         from application.user_data_report_daily
-        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb3 on tb1.advertiser_id = tb3.advertiser_id
         left join (select user_id, nick_name, phonenumber, dept_id from tidb.deepthink.sys_user) tb4
         on tb1.user_id=tb4.user_id
@@ -280,13 +289,13 @@
         left join
         (select advertiser_id, sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount, max(update_time) as update_time
         from application.media_ad_report_hourly
-        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb2 on tb1.advertiser_id = tb2.advertiser_id
         left join
         (select advertiser_id, sum(pay_amount) as pay_amount, sum(iaa_amount) as iaa_amount,
         sum(share_iaa_amount) as share_iaa_amount, sum(share_pay_amount) as share_pay_amount
         from application.user_data_report_hourly
-        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        where stat_date = #{date} and `hour`= #{hour} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb3 on tb1.advertiser_id = tb3.advertiser_id
         left join (select user_id, nick_name, phonenumber from tidb.deepthink.sys_user) tb4
         on tb1.user_id=tb4.user_id
@@ -303,11 +312,11 @@
         from
         (select cast(advertiser_id as char) advertiser_id, user_id from tidb.deepthink.advertiser_bind_info) tb1
         left join (select advertiser_id, sum(cost_amount) as cost_amount, sum(real_cost_amount) as real_cost_amount
-        from application.media_ad_report_daily where stat_date=#{date}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        from application.media_ad_report_daily where stat_date=#{date}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb2
         on tb1.advertiser_id = tb2.advertiser_id
         left join (select advertiser_id, sum(cost_amount) as cost_amount_hour
-        from application.media_ad_report_hourly where stat_date=#{date} and `hour`= ${hour}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        from application.media_ad_report_hourly where stat_date=#{date} and `hour`= ${hour}  and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb3
         on tb1.advertiser_id = tb3.advertiser_id
         left join (select user_id, nick_name, phonenumber, dept_id from tidb.deepthink.sys_user) tb4
@@ -387,8 +396,8 @@
         select tb4.dept_id, tb5.dept_name,
         rank() over (order by sum(cost_amount) desc) as rk,
         <include refid="costAmount"/>,
-        concat(round(if(ifnull(sum(iaa_real_cost_amount),0)=0, 0, sum(share_iaa_amount_3)/sum(iaa_real_cost_amount)*100), 2), '%') AS iaa_roi,
-        concat(round(if(ifnull(sum(iap_real_cost_amount),0)=0, 0, sum(share_pay_amount)/sum(iap_real_cost_amount)*100), 2), '%') AS iap_roi
+        <include refid="iaaRoi"/>,
+        <include refid="iapRoi"/>
         from
         (select cast(advertiser_id as char) advertiser_id, user_id from tidb.deepthink.advertiser_bind_info) tb1
         left join
@@ -398,11 +407,11 @@
         sum(iaa_real_cost_amount)+sum(iap_real_cost_amount) as real_cost_amount
         FROM
         (select advertiser_id, round(ifnull(sum(cost_amount),0),2) as iaa_cost_amount, sum(real_cost_amount) as iaa_real_cost_amount, 0 as iap_cost_amount, 0 as iap_real_cost_amount
-        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAA')
+        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAA')
         group by advertiser_id
         UNION ALL
         select advertiser_id, 0 as iaa_cost_amount, 0 as iaa_real_cost_amount,round(ifnull(sum(cost_amount),0),2) as cost_amount, sum(real_cost_amount) as real_cost_amount
-        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8) and business_method='IAP')
+        from application.media_ad_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11) and business_method='IAP')
         group by advertiser_id)subtb2
         group by advertiser_id
         ) tb2
@@ -411,7 +420,7 @@
         round(ifnull(sum(share_iaa_amount_3), 0),2) as share_iaa_amount_3,
         ifnull(sum(share_iaa_amount), 0) as share_iaa_amount,
         sum(share_pay_amount) as share_pay_amount
-        from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8))
+        from application.user_data_report_daily where stat_date=${date} and ma_appid in (select app_id from tidb.deepthink.mini_app_info where business_type in (1,3,8,9,10,11))
         group by advertiser_id) tb3
         on tb1.advertiser_id = tb3.advertiser_id
         left join (select user_id, nick_name, phonenumber, dept_id from tidb.deepthink.sys_user) tb4
@@ -454,6 +463,7 @@
     <select id="allBusinessPushData" resultType="java.util.Map">
         select
         <include refid="costAmount"/>,
+        <include refid="realCostAmount"/>,
         <include refid="payAmount"/>,
         <include refid="iaaAmount"/>,
         <include refid="shareIaaAmount"/>,

+ 6 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IBytedanceMaterialReportService.java

@@ -0,0 +1,6 @@
+package cn.com.ctop.job.bytedance.data.service;
+
+public interface IBytedanceMaterialReportService {
+    void getBytedanceMaterialDailyReport(Long advertiserId, String accessToken, String startDate, String endDate, Integer page,
+                                        Long errorId, Integer isLog, Integer isSend);
+}

+ 2 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IBytedanceMiniAppService.java

@@ -6,6 +6,8 @@ import java.util.List;
 
 public interface IBytedanceMiniAppService {
     List<String> getIaaAppIds();
+    List<String> getAllAppIds();
     void getMaEcpm(String startDt, String endDt, String appId, Integer isLog, Long errId, Integer isSend);
     List<JSONObject> getMaEcpmRetryJob();
+    void getAdPlacement(String appId);
 }

+ 12 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/ICsjResourceService.java

@@ -0,0 +1,12 @@
+package cn.com.ctop.job.bytedance.data.service;
+
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumResourceInfo;
+
+import java.util.List;
+
+public interface ICsjResourceService {
+
+    List<CsjAlbumResourceInfo> albumList();
+
+    String run(CsjAlbumResourceInfo album);
+}

+ 12 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IDianZhongService.java

@@ -0,0 +1,12 @@
+package cn.com.ctop.job.bytedance.data.service;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.List;
+
+public interface IDianZhongService {
+    void getDownloadUrl(String dataType, String clientId, String token,
+                        String startTime, String endTime,Long errId,boolean isLog);
+    List<JSONObject> getDZRetry();
+    void getUrlData(String statDate);
+}

+ 4 - 1
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/AdminAdvertiserListServiceImpl.java

@@ -14,12 +14,14 @@ import org.springframework.stereotype.Service;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.stream.Collectors;
+
 @Service
 @Slf4j
 public class AdminAdvertiserListServiceImpl implements IAdminAdvertiserListService {
 
     @Autowired
     private AdminAdvertiserListMapper adminAdvertiserListMapper;
+
     @Override
     public JSONObject bytedanceAdvertiserThreadPool(Integer totalPage, Integer pageSize, Long adminAdvertiserId, Long ccAccountId, String accessToken) {
         ExecutorService executor = Executors.newFixedThreadPool(5);
@@ -136,7 +138,7 @@ public class AdminAdvertiserListServiceImpl implements IAdminAdvertiserListServi
     }
 
 
-    private List<String> getBytedanceAccountList(Long adminAdvertiserId, Long ccAccountId, String accessToken, Integer page, Integer pageSize, Integer requestCount) {
+    private List<String> getBytedanceAccountList(Long adminAdvertiserId, Long ccAccountId, String accessToken, Integer page, Integer pageSize, Integer requestCount) throws InterruptedException {
         try {
             Thread.sleep(100);
         } catch (InterruptedException e) {
@@ -176,6 +178,7 @@ public class AdminAdvertiserListServiceImpl implements IAdminAdvertiserListServi
             }
         } else {
             log.error("请求字节账户列表失败,进入重试任务,当前请求次数:{}", requestCount);
+            Thread.sleep(1000);
             getBytedanceAccountList(adminAdvertiserId, ccAccountId, accessToken, page, pageSize, requestCount + 1);
         }
         if (!Check.isNull(advertiserLists)) {

+ 61 - 2
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceCdpProjectServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.ctop.job.bytedance.utils.doris.sink.DorisMultiTableStreamLoadManag
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -114,15 +115,16 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
                     JSONArray array = data.getJSONArray("list");
                     for (int i = 0; i < array.size(); i++) {
                         JSONObject jsonObject = array.getJSONObject(i);
+                        jsonObject.put("promotion_list", jsonObject.toJSONString());
                         checkPromotionInfo(jsonObject, advertiserId);
                         dorisLoadManager.add("media_api", "bytedance_promotion_list", jsonObject);
                     }
 
-                    if (!Check.isNull(array)) {
+                    /*if (!Check.isNull(array)) {
                         //bytedanceCdpProjectMapper.replaceBytedancePromotionListSD(array);
                         if (bytedanceCdpProjectMapper.replaceBytedancePromotionList(array) > 0)
                             log.info("---账户({})广告更新成功", advertiserId);
-                    }
+                    }*/
                 } else {
                     //40100请求超频
                     if (40100 == code && count <= 5) {
@@ -154,6 +156,10 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
                 entity.put("url", miniProgramInfo.getString("url"));
             }
         }
+        JSONObject nativeSetting = entity.getJSONObject("native_setting");
+        if (!Check.isNull(nativeSetting)) {
+            entity.put("aweme_id", nativeSetting.getString("aweme_id"));
+        }
     }
 
     @Override
@@ -398,6 +404,7 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
                         for (Object o : list) {
                             JSONObject json = (JSONObject) o;
                             json.put("advertiser_id", advertiserId);
+                            json.put("app_name", json.getString("name"));
                             dorisLoadManager.add("media_api", "bytedance_wx_app_info", json);
                         }
                     }
@@ -529,6 +536,8 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
         }
         if (nextPage) {
             rebackadqCreativesVo(accountId, accessToken, startDate, endDate, page + 1, isDeleted, 1);
+        }else{
+            log.info("账户({})获取动态创意完成", accountId);
         }
     }
 
@@ -632,6 +641,56 @@ public class BytedanceCdpProjectServiceImpl implements IBytedanceCdpProjectServi
     private void getAppId(JSONObject object) {
         JSONObject creativeComponents = object.getJSONObject("creative_components");
         if (!Check.isNull(creativeComponents)) {
+            List<String> imageIds = new ArrayList<>();
+            List<String> videoIds = new ArrayList<>();
+            JSONArray videoArr = creativeComponents.getJSONArray("video");
+            if(!Check.isNull(videoArr)) {
+                for (int i = 0; i < videoArr.size(); i++) {
+                    JSONObject obj = videoArr.getJSONObject(i);
+                    JSONObject value = obj.getJSONObject("value");
+                    if (!Check.isNull(value)) {
+                        String videoId = value.getString("video_id");
+                        if (StringUtils.isNotBlank(videoId)) videoIds.add(videoId);
+                    }
+                }
+            }
+            JSONArray imageArr = creativeComponents.getJSONArray("image");
+            if(!Check.isNull(imageArr)) {
+                for (int i = 0; i < imageArr.size(); i++) {
+                    JSONObject obj = imageArr.getJSONObject(i);
+                    JSONObject value = obj.getJSONObject("value");
+                    if (!Check.isNull(value)) {
+                        String imageId = value.getString("image_id");
+                        if (StringUtils.isNotBlank(imageId)) imageIds.add(imageId);
+                    }
+                }
+            }
+            JSONArray imageListArr = creativeComponents.getJSONArray("image_list");
+            if(!Check.isNull(imageListArr)) {
+                for (int i = 0; i < imageListArr.size(); i++) {
+                    JSONObject obj = imageListArr.getJSONObject(i);
+                    JSONObject value = obj.getJSONObject("value");
+                    if (!Check.isNull(value)) {
+                        JSONArray list = value.getJSONArray("list");
+                        if (!Check.isNull(list)) {
+                            for (int j = 0; j < list.size(); j++) {
+                                JSONObject image = list.getJSONObject(j);
+                                if (!Check.isNull(image)) {
+                                    String imageId = image.getString("image_id");
+                                    if (StringUtils.isNotBlank(imageId)) imageIds.add(imageId);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if (!Check.isNull(videoIds)){
+                object.put("video_list", StringUtils.join(videoIds, ","));
+            }
+            if (!Check.isNull(imageIds)){
+                object.put("image_list", StringUtils.join(imageIds, ","));
+            }
+
             JSONArray textLink = creativeComponents.getJSONArray("text_link");
             if (!Check.isNull(textLink)) {
                 JSONObject value = textLink.getJSONObject(0).getJSONObject("value");

+ 112 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceMaterialReportServiceImpl.java

@@ -0,0 +1,112 @@
+package cn.com.ctop.job.bytedance.data.service.impl;
+
+import cn.com.ctop.job.bytedance.data.entity.BytedanceErrorLog;
+import cn.com.ctop.job.bytedance.data.mapper.BytedancePromoterReportMapper;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceMaterialReportService;
+import cn.com.ctop.job.bytedance.data.utils.AlertUtils;
+import cn.com.ctop.job.bytedance.data.utils.Check;
+import cn.com.ctop.job.bytedance.data.utils.FieldsConfig;
+import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
+import cn.com.ctop.job.bytedance.utils.doris.sink.DorisMultiTableStreamLoadManager;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class BytedanceMaterialReportServiceImpl implements IBytedanceMaterialReportService {
+    @Autowired
+    private BytedancePromoterReportMapper promoterReportMapper;
+    @Autowired
+    private DorisMultiTableStreamLoadManager dorisLoadManager;
+
+    @Override
+    public void getBytedanceMaterialDailyReport(Long advertiserId, String accessToken, String startDate, String endDate, Integer page, Long errorId, Integer isLog, Integer isSend) {
+        try {
+            String url = "https://api.oceanengine.com/open_api/v3.0/report/custom/get/";
+            Map<String, Object> paramsMap = new HashMap<>();
+            paramsMap.put("advertiser_id", advertiserId);
+            paramsMap.put("start_time", startDate);
+            paramsMap.put("end_time", endDate);
+            paramsMap.put("data_topic", "BASIC_DATA");
+            paramsMap.put("metrics", FieldsConfig.getMaterialMetrics());
+            paramsMap.put("dimensions", FieldsConfig.getMaterialDailyDimensions());
+            paramsMap.put("order_by", new JSONArray());
+            paramsMap.put("filters", new JSONArray());
+            paramsMap.put("page", page);
+            paramsMap.put("page_size", 100);
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Access-Token", accessToken);
+            headers.put("Content-Type", "application/json");
+            String s = HttpUtils.httpGet(url, paramsMap, headers);
+            JSONObject result = JSONObject.parseObject(s);
+            if (Check.isNull(result)) {
+                log.info("账户id:{},素材日报请求结果返回为空", advertiserId);
+                if (isLog == 1) {
+                    BytedanceErrorLog errorInfo = new BytedanceErrorLog();
+                    errorInfo.setAdvertiserId(advertiserId);
+                    errorInfo.setStartDate(startDate);
+                    errorInfo.setEndDate(endDate);
+                    errorInfo.setDataDimension("material");
+                    errorInfo.setDataType("daily");
+                    errorInfo.setMsg("请求结果返回为空");
+                    promoterReportMapper.replaceErrorInfo(errorInfo);
+                }
+                return;
+            }
+            Integer code = result.getInteger("code");
+            int totalPage = 1;
+            if (code == 0) {
+                JSONObject data = result.getJSONObject("data");
+                if (!Check.isNull(data)) {
+                    totalPage = data.getJSONObject("page_info").getIntValue("total_page");
+                    JSONArray rows = data.getJSONArray("rows");
+                    if (!Check.isNull(rows)) {
+                        for (int i = 0; i < rows.size(); i++) {
+                            JSONObject rowJson = rows.getJSONObject(i);
+                            JSONObject metricsJson = rowJson.getJSONObject("metrics");
+                            JSONObject dimensionsJson = rowJson.getJSONObject("dimensions");
+
+                            dimensionsJson.putAll(metricsJson);
+                            dimensionsJson.put("stat_time_day", dimensionsJson.getString("stat_time_day").replace("-", ""));
+                            dimensionsJson.put("advertiser_id", advertiserId);
+                            dorisLoadManager.add("media_api", "bytedance_material_report_daily", dimensionsJson);
+                        }
+                    }
+                }
+            } else {
+                log.info("账户id:{},日期:{}素材日报请求结果失败,返回数据:{}", advertiserId, startDate, result);
+                if (isLog == 1) {
+                    BytedanceErrorLog errorInfo = new BytedanceErrorLog();
+                    errorInfo.setAdvertiserId(advertiserId);
+                    errorInfo.setStartDate(startDate);
+                    errorInfo.setEndDate(endDate);
+                    errorInfo.setDataDimension("material");
+                    errorInfo.setDataType("daily");
+                    errorInfo.setMsg(result.getString("message"));
+                    promoterReportMapper.replaceErrorInfo(errorInfo);
+                }
+                return;
+            }
+            if (page < totalPage) {
+                getBytedanceMaterialDailyReport(advertiserId, accessToken, startDate, endDate, page + 1, errorId, isLog, isSend);
+            } else {
+                log.info("账户ID:{}, 开始日期:{}, 结束日期:{}, totalPage:{}, 素材日报数据请求成功", advertiserId, startDate, endDate, totalPage);
+                if (errorId != null) {
+                    promoterReportMapper.deleteInfoByErrorId(errorId);
+                }
+                if (isSend != null && 1 == isSend) {
+                    AlertUtils.sendMessage(advertiserId, startDate, endDate, 1, "material", 1, null);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+
+        }
+    }
+}

+ 57 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceMiniAppServiceImpl.java

@@ -22,6 +22,15 @@ import java.util.Map;
 @Service
 @Slf4j
 public class BytedanceMiniAppServiceImpl implements IBytedanceMiniAppService {
+    private static final Map<Integer,String> adPlacementMap = new HashMap<Integer,String>(){{
+        put(1,"banner");
+        put(2,"激励视频广告");
+        put(3,"信息流广告");
+        put(4,"插屏广告");
+        put(5,"视频前贴片广告");
+        put(6,"视频后贴片广告");
+        put(9,"视频流广告");
+    }};
     @Resource
     private RedisTemplate redis2Template_db5;
 
@@ -37,11 +46,59 @@ public class BytedanceMiniAppServiceImpl implements IBytedanceMiniAppService {
     }
 
     @Override
+    public List<String> getAllAppIds() {
+        return bytedanceMiniAppMapper.getAllAppIds();
+    }
+
+    @Override
     public List<JSONObject> getMaEcpmRetryJob() {
         return bytedanceMiniAppMapper.getMaEcpmRetryJob();
     }
 
     @Override
+    public void getAdPlacement(String appId) {
+        try {
+            String url = "https://open.douyin.com/api/apps/v1/ad_placement/query/";
+            Object tokenObj = redis2Template_db5.opsForValue().get("client-token-key_" + appId);
+            if (tokenObj == null) {
+                log.error("抖小广告位列表拉取获取token为空 [{}]", appId);
+                return;
+            }
+
+            HashMap<String, String> headers = new HashMap<>();
+            headers.put("access-token", tokenObj.toString());
+            headers.put("Content-Type", "application/json; charset=UTF-8");
+
+            String s = HttpUtils.httpGet(url,null,headers);
+            JSONObject jsonObject = JSONObject.parseObject(s);
+
+            if (!Check.isNull(jsonObject)) {
+                Integer code = jsonObject.getInteger("err_no");
+                if (code == 0) {
+                    JSONObject data = jsonObject.getJSONObject("data");
+
+                    JSONArray result = data.getJSONArray("ad_placement_list");
+                    if (!Check.isNull(result)) {
+                        for (int i = 0; i < result.size(); i++) {
+                            JSONObject resultJson = result.getJSONObject(i);
+                            resultJson.put("app_id", appId);
+                            resultJson.put("ad_placement_type_name", adPlacementMap.get(resultJson.getInteger("ad_placement_type")));
+                        }
+                        bytedanceMiniAppMapper.insertAdPlacement(result);
+                    }
+                } else {
+                    log.error("[{}]抖小广告位列表拉取失败,返回信息:{}", appId, s);
+                }
+            } else {
+                log.error("[{}]抖小广告位列表拉取返回数据为空", appId);
+            }
+            log.info("[{}]抖小广告位列表拉取返回数据完成。", appId);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    @Override
     public void getMaEcpm(String startDt, String endDt, String appId, Integer isLog, Long errId, Integer isSend) {
         try {
             Long dataRangeSeconds = 3600L;

+ 27 - 7
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceProductUpdateServiceImpl.java

@@ -35,10 +35,10 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
     public void run() throws Exception {
         Set<String> errors = new HashSet<>();
         log.info("付费商品库更新中...");
-//        iapProductUpdate(errors);
+        iapProductUpdate(errors);
         log.info("付费商品库更新完成");
         log.info("免费商品库更新中...");
-        iaaProductUpdate(errors);
+//        iaaProductUpdate(errors);
         log.info("免费商品库更新完成");
         if (!Check.isNull(errors)){
             List<String> info = new ArrayList<>();
@@ -455,7 +455,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
      * @return map key: album_id, value: 对应的字节小程序推广链接,sslocal开头
      */
     private Map<String, String> getBytedancePlayletPromoteLink(String advertiserId, String accessToken, String instanceId, List<JSONObject> requests, Set<String> errorBlanket){
-        JSONArray playletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceId, errorBlanket);
+        JSONArray playletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceId, errorBlanket,1);
         if (playletDetailInfo == null || playletDetailInfo.isEmpty()){
             return null;
         }
@@ -524,7 +524,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                     continue;
                 }else {
                     String instanceid = jsonObject.getJSONObject("data").getString("instance_id");
-                    JSONArray newPlayletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceid, errorBlanket);
+                    JSONArray newPlayletDetailInfo = getPlayletDetail(advertiserId, accessToken, instanceid, errorBlanket,1);
                     if (newPlayletDetailInfo == null || newPlayletDetailInfo.isEmpty()){
                         continue;
                     }
@@ -542,7 +542,19 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
 
     }
 
-    private JSONArray getPlayletDetail(String advertiserId, String accessToken, String instanceId, Set<String> errorBlanket) {
+    /**
+     * 获取字节小程序中的推广链接
+     * @param advertiserId
+     * @param accessToken
+     * @param instanceId
+     * @param errorBlanket
+     * @param pageNum 从外部调用填1
+     * @return
+     */
+    private JSONArray getPlayletDetail(String advertiserId, String accessToken, String instanceId, Set<String> errorBlanket, Integer pageNum) {
+        if (pageNum >50){
+            return new JSONArray();
+        }
         String getPlayletDetailUrl = "https://api.oceanengine.com/open_api/v3.0/tools/asset_link/list/";
         getPlayletDetailUrl = getPlayletDetailUrl.replace("${ADVERTISER_ID}", advertiserId);
         getPlayletDetailUrl = getPlayletDetailUrl.replace("${INSTANCE_ID}", instanceId);
@@ -550,7 +562,7 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
         headers.put("Access-Token", accessToken);
         Map<String, Object> params = new HashMap<>();
         params.put("advertiser_id", advertiserId);
-        params.put("page", "1");
+        params.put("page", String.valueOf(pageNum));
         params.put("page_size", "100");
         params.put("filtering", "{\"instance_id\":" + instanceId + "}");
         String res = HttpUtils.httpGet(getPlayletDetailUrl, params, headers);
@@ -565,7 +577,15 @@ public class BytedanceProductUpdateServiceImpl implements IBytedanceProductUpdat
                 System.out.println("获取字节小程序推广链接失败,code: " + code + ", msg: " + jsonObject.getString("message"));
                 return null;
             }else {
-                return jsonObject.getJSONObject("data").getJSONArray("list");
+                JSONArray list = jsonObject.getJSONObject("data").getJSONArray("list");
+                JSONObject page_info = jsonObject.getJSONObject("data").getJSONObject("page_info");
+                int total_page = page_info.getIntValue("total_page");
+                if (total_page > pageNum){
+                    //递归获取下一页
+                    JSONArray nextPage = getPlayletDetail(advertiserId, accessToken, instanceId, errorBlanket, pageNum + 1);
+                    list.addAll(nextPage);
+                }
+                return list;
             }
         }
 

+ 169 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/CsjResourceServiceImpl.java

@@ -0,0 +1,169 @@
+package cn.com.ctop.job.bytedance.data.service.impl;
+
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumResourceInfo;
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumSeqResourceInfo;
+import cn.com.ctop.job.bytedance.data.mapper.CsjResourceMapper;
+import cn.com.ctop.job.bytedance.data.service.ICsjResourceService;
+import cn.com.ctop.job.bytedance.data.utils.Check;
+import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
+import cn.com.ctop.job.bytedance.utils.OssProperties;
+import cn.com.ctop.job.bytedance.utils.OssUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class CsjResourceServiceImpl implements ICsjResourceService {
+
+    @Resource
+    CsjResourceMapper csjResourceMapper;
+    @Autowired
+    OssUtil ossUtil;
+    @Autowired
+    OssProperties ossProperties;
+
+    @Override
+    public List<CsjAlbumResourceInfo> albumList() {
+        return csjResourceMapper.getResources();
+    }
+
+    @Override
+    public String run(CsjAlbumResourceInfo album) {
+        String resourceId = album.getResourceId();
+        String albumId = album.getAlbumId();
+        String token = csjResourceMapper.getToken();
+        if (Check.isNull(token)){
+            return "获取token失败";
+        }
+
+        String csjDownloadUrl = "https://open.douyin.com/api/resource_library/v1/resource/download/";
+        Map<String, String> headers = new HashMap<>();
+        headers.put("access-token", token);
+        headers.put("Content-Type", "application/json");
+        Map<String, Object> params = new HashMap<>();
+        params.put("resource_id", resourceId);
+        String res = HttpUtils.httpPostRequest(csjDownloadUrl, params, headers);
+        if (Check.isNull(res)) {
+            return "请求失败,返回结果为空";
+        }
+        JSONObject resObj = JSONObject.parseObject(res);
+        int err_no = resObj.getInteger("err_no");
+        if (err_no != 0) {
+            return "请求失败,错误码:" + err_no + ", 错误信息:" + resObj.getString("err_msg");
+        }
+        JSONObject data = resObj.getJSONObject("data");
+        JSONArray videoList = data.getJSONArray("video_info_list");
+        JSONArray coverList = data.getJSONArray("cover_info_list");
+
+
+        List<CsjAlbumSeqResourceInfo> seqList = album.getSeqList();
+        if (seqList == null){
+            seqList = new ArrayList<>();
+        }else {
+            seqList.removeIf(seq -> seq.getSeq() == null);
+        }
+        Map<Integer, CsjAlbumSeqResourceInfo> seqMap = seqList.stream().collect(Collectors.toMap(CsjAlbumSeqResourceInfo::getSeq, seq -> seq));
+
+        //先存图
+        //获取一个最大的seq值,来判断上传是否完成
+        if (coverList != null && !coverList.isEmpty()){
+            int maxSeq = 0;
+            for (int i = 0; i < coverList.size(); i++) {
+                JSONObject coverInfo = coverList.getJSONObject(i);
+                Integer seqNum = coverInfo.getInteger("seq");
+                if (seqNum == null || seqNum == 0){
+                    maxSeq = 0;
+                    break; //封面图不需要seq
+                } else {
+                    maxSeq = Math.max(maxSeq, seqNum);
+                }
+            }
+
+
+            for (int i = 0; i < coverList.size(); i++) {
+                JSONObject coverInfo = coverList.getJSONObject(i);
+                Integer seqNum = coverInfo.getInteger("seq");
+                String coverUrl = coverInfo.getString("url");
+
+                if (seqNum == null || seqNum == 0){
+                    if (StringUtils.isEmpty(album.getOssCoverImg())){
+                        String fileName = albumId + "_cover.jpg";
+                        String ossCoverImg = uploadToOss(coverUrl, fileName);
+                        if (StringUtils.isNotEmpty(ossCoverImg)){
+                            album.setOssCoverImg(ossCoverImg);
+                        }
+                        csjResourceMapper.updateAlbum(album);
+                    }
+                } else {
+                    CsjAlbumSeqResourceInfo seq = seqMap.get(seqNum);
+                    if (seq == null){
+                        seq = new CsjAlbumSeqResourceInfo(albumId, seqNum);
+                        seqList.add(seq);
+                        seqMap.put(seqNum, seq);
+                    }
+                    if (StringUtils.isEmpty(seq.getOssSeqImg())){
+                        String fileName = albumId + "_" + seqNum + "_image.jpg";
+                        String ossSeqImg = uploadToOss(coverUrl, fileName);
+                        if (StringUtils.isNotEmpty(ossSeqImg)){
+                            seq.setOssSeqImg(ossSeqImg);
+                        }
+                        csjResourceMapper.updateSeq(seq);
+                    }
+                }
+            }
+        }
+        if (videoList != null && !videoList.isEmpty()){
+            for (int i = 0; i < videoList.size(); i++) {
+                JSONObject videoInfo = videoList.getJSONObject(i);
+                Integer seqNum = videoInfo.getInteger("seq");
+                String videoUrl = videoInfo.getString("url");
+                if (Check.isNull(videoUrl)) {
+                    log.error("第" + seqNum + "集视频链接为空");
+                }
+                CsjAlbumSeqResourceInfo seq = seqMap.get(seqNum);
+                if (seq == null){
+                    seq = new CsjAlbumSeqResourceInfo(albumId, seqNum);
+                    seqList.add(seq);
+                    seqMap.put(seqNum, seq);
+                }
+                if (StringUtils.isEmpty(seq.getOssSeqVideo())){
+                    String fileName = albumId + "_" + seqNum + "_video.mp4";
+                    String ossVideoUrl = uploadToOss(videoUrl, fileName);
+                    if (StringUtils.isNotEmpty(ossVideoUrl)){
+                        seq.setOssSeqVideo(ossVideoUrl);
+                    }
+                    csjResourceMapper.updateSeq(seq);
+
+                }
+            }
+        }
+
+        log.info("处理资源成功: " + album.getAlbumId() + ", 共处理分集: " + seqList.size());
+
+        return "";
+    }
+
+    private String uploadToOss(String url, String fileName){
+        String objectKey = ossProperties.getCsjFileDir() + fileName;
+        String ossUrl = ossProperties.getCsjDomain() + objectKey;
+        try {
+            System.out.println("文件: "+fileName + ", from: " + url);
+            ossUtil.uploadFromUrl(objectKey, url);
+            log.info("上传成功: " + ossUrl);
+            return ossUrl;
+        } catch (Exception e) {
+            log.error("上传失败: " + e.getMessage(), e);
+            return null;
+        }
+    }
+
+
+}

+ 2 - 1
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/DateReportsPushServiceImpl.java

@@ -33,7 +33,7 @@ public class DateReportsPushServiceImpl implements IDateReportsPushService {
     @Autowired
     ReportsAdPushMapper reportsPushMapper;
 
-    private static final String TEMPLATE_VERSION = "1.0.12";
+    private static final String TEMPLATE_VERSION = "1.0.13";
     private static final String TEMPLATE_ID = "AAqRhJzMBoO0E";
 
     /**
@@ -115,6 +115,7 @@ public class DateReportsPushServiceImpl implements IDateReportsPushService {
         String updateTime = reportsPushMapper.updateTime(todayLong);
         List<Pair<String, String>> columns = Arrays.asList(
                 new Pair<>("cost_amount", "消耗金额"),
+                new Pair<>("real_cost_amount", "折后消耗"),
                 new Pair<>("end_amount", "结算金额"),
                 new Pair<>("pay_amount", "充值金额"),
                 new Pair<>("share_iaa_amount", "广告预估收入"),

+ 293 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/DianZhongServiceImpl.java

@@ -0,0 +1,293 @@
+package cn.com.ctop.job.bytedance.data.service.impl;
+
+import cn.com.ctop.job.bytedance.data.entity.BytedanceErrorLog;
+import cn.com.ctop.job.bytedance.data.mapper.BytedancePromoterReportMapper;
+import cn.com.ctop.job.bytedance.data.mapper.DianZhongMapper;
+import cn.com.ctop.job.bytedance.data.service.IDianZhongService;
+import cn.com.ctop.job.bytedance.data.utils.Check;
+import cn.com.ctop.job.bytedance.data.utils.DateUtils;
+import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
+import cn.com.ctop.job.bytedance.utils.doris.sink.DorisMultiTableStreamLoadManager;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.ResponseExtractor;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class DianZhongServiceImpl implements IDianZhongService {
+    @Autowired
+    private DorisMultiTableStreamLoadManager dorisLoadManager;
+
+    @Autowired
+    private BytedancePromoterReportMapper promoterReportMapper;
+
+    @Autowired
+    private RestTemplate downloadFileRestTemplate;
+
+    @Autowired
+    private DianZhongMapper dianZhongMapper;
+
+    private static final Map<Integer, Integer> domain2Platform = new HashMap<Integer, Integer>() {{
+        put(14, 2);//抖小
+        put(16, 1);//微小
+        put(17, 3);//快小
+    }};
+
+    private static final Map<String, String> clientDomain2AppId = new HashMap<String, String>() {{
+        put("10003129" + "14", "dzdyIAP");//抖小
+    }};
+
+    private static final Map<String, String> media2Id = new HashMap<String, String>() {{
+        put("adq", "3");//腾讯广点通
+        put("dy", "1");//字节巨量
+        put("ks", "2");//快手-磁力
+    }};
+
+    public List<JSONObject> getDZRetry() {
+        return dianZhongMapper.getDZRetry();
+    }
+
+    /*
+    获取点众IAP数据下载url
+     */
+    public void getDownloadUrl(String dataType, String clientId, String token,
+                               String startTime, String endTime, Long errId, boolean isLog) {
+        long l = System.currentTimeMillis();
+        JSONObject param = new JSONObject()
+                .fluentPut("clientId", clientId)
+                .fluentPut("sdate", String.valueOf(DateUtil.parse(startTime, "yyyy-MM-dd HH:mm:ss").getTime() / 1000))
+                .fluentPut("edate", String.valueOf(DateUtil.parse(endTime, "yyyy-MM-dd HH:mm:ss").getTime() / 1000))
+                .fluentPut("timestamp", l)
+                .fluentPut("signKey", getSignKey(clientId, token, l));
+        if ("user".equals(dataType)) {
+            param.put("queryField", "loginTime");
+        }
+        try {
+            String url = "https://routine.wqxsw.com/flames/channel/query/" + dataType;
+            String response = HttpUtils.httpPostRequest(url, param, null);
+            JSONObject responseJson = JSONObject.parseObject(response);
+            if ("0".equals(responseJson.getString("retCode"))) {
+                String taskId = responseJson.getString("data");
+                JSONObject jsonObject = new JSONObject()
+                        .fluentPut("stat_date", DateUtils.transformFormat(endTime, "yyyy-MM-dd HH:mm:ss", "yyyyMMdd"))
+                        .fluentPut("task_id", taskId)
+                        .fluentPut("type", dataType)
+                        .fluentPut("client_id", clientId)
+                        .fluentPut("start_time", startTime)
+                        .fluentPut("end_time", endTime);
+                dianZhongMapper.insertDownloadTask(jsonObject);
+                log.info("获取点众{}数据下载地址成功 {} {}~{} taskId:{}", dataType, clientId, startTime, endTime, taskId);
+
+                if (errId != null) {
+                    promoterReportMapper.deleteInfoByErrorId(errId);
+                }
+            } else {
+                log.error("获取点众{}数据下载地址错误 {} {}~{} msg:{}", dataType, clientId, startTime, endTime, responseJson.getString("retMsg"));
+                if (isLog) {
+                    promoterReportMapper.replaceErrorInfo(
+                            BytedanceErrorLog.builder()
+                                    .msg(responseJson.getString("retMsg"))
+                                    .advertiserId(Long.valueOf(clientId))
+                                    .dataDimension("dianzhong_url")
+                                    .dataType(dataType)
+                                    .startDate(startTime)
+                                    .endDate(endTime)
+                                    .build());
+                }
+            }
+        } catch (Exception e) {
+            log.error("获取点众{}数据下载地址错误 {} {}~{} ", dataType, clientId, startTime, endTime, e);
+            if (isLog) {
+                promoterReportMapper.replaceErrorInfo(
+                        BytedanceErrorLog.builder()
+                                .msg(e.getMessage())
+                                .advertiserId(Long.valueOf(clientId))
+                                .dataDimension("dianzhong_url")
+                                .dataType(dataType)
+                                .startDate(startTime)
+                                .endDate(endTime)
+                                .build());
+            }
+        }
+    }
+
+    /*
+    下载点众IAP数据
+     */
+    public void getUrlData(String statDate) {
+        List<JSONObject> tasks = dianZhongMapper.getTaskUrl(statDate.replace("-", ""));
+        if (!Check.isNull(tasks)) {
+            for (JSONObject task : tasks) {
+                String taskId = task.getString("task_id");
+                String url = task.getString("url");
+                String type = task.getString("type");
+                String clientId = task.getString("client_id");
+
+                downloadFileRestTemplate.execute(url, org.springframework.http.HttpMethod.GET, null,
+                        (ResponseExtractor<Void>) response -> {
+                            try (BufferedReader reader = new BufferedReader(
+                                    new InputStreamReader(response.getBody(), StandardCharsets.UTF_8))) {
+                                String line;
+                                while ((line = reader.readLine()) != null) {
+                                    if ("user".equals(type)) {
+                                        JSONObject dzUser = getDZUser(line, clientId);
+                                        dorisLoadManager.add("hr_playlet", "user_event", dzUser);
+                                        JSONObject dzLogin = getDZLogin(line, clientId);
+                                        dorisLoadManager.add("hr_playlet", "server_event", dzLogin);
+                                    } else if ("order".equals(type)) {
+                                        JSONObject dzOrder = getDZOrder(line, clientId);
+                                        dorisLoadManager.add("hr_playlet", "server_event", dzOrder);
+                                    }
+                                }
+                            }
+                            return null;
+                        });
+                dianZhongMapper.updateTaskDownloaded(taskId);
+            }
+        }
+    }
+
+    private static String getSignKey(String clientId, String token, long timeStamp) {
+        return SecureUtil.md5(clientId + token + timeStamp).toLowerCase();
+    }
+
+    private static JSONObject getDZUser(String line, String clientId) {
+        JSONObject jsonObject = JSONObject.parseObject(line);
+        JSONObject userJson = new JSONObject();
+        int domain = jsonObject.getIntValue("domain");
+        String appId = clientId + domain;
+        Long ctime = jsonObject.getLong("ctime");
+        String statDate = DateUtils.formatDate(ctime * 1000, "yyyyMMdd");
+        String registerTime = DateUtils.formatDate(ctime * 1000, "yyyy-MM-dd HH:mm:ss");
+        String adId = jsonObject.getString("adid");
+        String promotionId = jsonObject.getString("promotionId");
+        adId = StringUtils.isNotBlank(promotionId) ? promotionId : adId;
+        Long dyeTime = jsonObject.getLong("dyeTime");
+        String activationTime = DateUtils.formatDate(dyeTime * 1000, "yyyy-MM-dd HH:mm:ss");
+        String fromMedia = jsonObject.getString("from");
+        userJson.put("app_id", clientDomain2AppId.getOrDefault(appId, appId));
+        userJson.put("uid", jsonObject.getString("userId"));
+        userJson.put("stat_date", statDate);
+        userJson.put("register_time", registerTime);
+        userJson.put("created_at", ctime);
+        userJson.put("open_id", jsonObject.getString("openId"));
+        userJson.put("platform", domain2Platform.getOrDefault(domain, domain));
+        userJson.put("official_account_open_id", jsonObject.getString("thirdWxId"));
+        userJson.put("channel_id", jsonObject.getString("channelId"));
+        userJson.put("link_id", jsonObject.getString("referralId"));
+        userJson.put("expiration_time", jsonObject.getString("vipEndDate"));
+        userJson.put("pay_amount", jsonObject.getString("payAmount"));
+        userJson.put("pay_count", jsonObject.getString("payCount"));
+        userJson.put("last_login_time", jsonObject.getString("loginTime"));
+        userJson.put("ip", jsonObject.getString("ip"));
+        userJson.put("mobile_system", jsonObject.getIntValue("os") == 0 ? "Android" : "ios");
+        userJson.put("person_id", jsonObject.getString("kdrId"));
+        userJson.put("a_id", jsonObject.getString("projectId"));
+        userJson.put("ad_id", adId);
+        userJson.put("activation_time", activationTime);
+        userJson.put("media_id", media2Id.getOrDefault(fromMedia, fromMedia));
+        return userJson;
+    }
+
+    private static JSONObject getDZLogin(String line, String clientId) {
+        JSONObject jsonObject = JSONObject.parseObject(line);
+        JSONObject loginJson = new JSONObject();
+        int domain = jsonObject.getIntValue("domain");
+        String appId = clientId + domain;
+        Long loginTime = jsonObject.getLong("loginTime");
+        String statDate = DateUtils.formatDate(loginTime * 1000, "yyyyMMdd");
+        String adId = jsonObject.getString("adid");
+        String promotionId = jsonObject.getString("promotionId");
+        adId = StringUtils.isNotBlank(promotionId) ? promotionId : adId;
+        Long dyeTime = jsonObject.getLong("dyeTime");
+        String activationTime = DateUtils.formatDate(dyeTime * 1000, "yyyy-MM-dd HH:mm:ss");
+        String fromMedia = jsonObject.getString("from");
+        String userId = jsonObject.getString("userId");
+        loginJson.put("stat_date", statDate);
+        loginJson.put("event", "LOGIN");
+        loginJson.put("event_pk", SecureUtil.md5(String.format("dianzhong_login_%s_%s", userId, loginTime)));
+        loginJson.put("event_tag", "dianzhong_login");
+        loginJson.put("app_id", clientDomain2AppId.getOrDefault(appId, appId));
+
+        loginJson.put("uid", userId);
+        loginJson.put("open_id", jsonObject.getString("openId"));
+        loginJson.put("platform", domain2Platform.getOrDefault(domain, domain));
+        loginJson.put("official_account_open_id", jsonObject.getString("thirdWxId"));
+        loginJson.put("channel_id", jsonObject.getString("channelId"));
+        loginJson.put("link_id", jsonObject.getString("referralId"));
+        loginJson.put("register_date", jsonObject.getString("registerDate"));
+        loginJson.put("expiration_time", jsonObject.getString("vipEndDate"));
+        loginJson.put("last_login_time", jsonObject.getString("loginTime"));
+        loginJson.put("created_at", loginTime);
+        loginJson.put("ip", jsonObject.getString("ip"));
+        loginJson.put("mobile_system", jsonObject.getIntValue("os") == 0 ? "Android" : "ios");
+        loginJson.put("person_id", jsonObject.getString("kdrId"));
+        loginJson.put("a_id", jsonObject.getString("projectId"));
+        loginJson.put("ad_id", adId);
+        loginJson.put("activation_time", activationTime);
+        loginJson.put("media_id", media2Id.getOrDefault(fromMedia, fromMedia));
+        return loginJson;
+    }
+
+    private static JSONObject getDZOrder(String line, String clientId) {
+        JSONObject jsonObject = JSONObject.parseObject(line);
+        JSONObject orderJson = new JSONObject();
+        String orderId = jsonObject.getString("id");
+        int domain = jsonObject.getIntValue("domain");
+        String appId = clientId + domain;
+        Long ctime = jsonObject.getLong("ctime");
+        String statDate = DateUtils.formatDate(ctime * 1000, "yyyyMMdd");
+        String adId = jsonObject.getString("adid");
+        String promotionId = jsonObject.getString("promotionId");
+        adId = StringUtils.isNotBlank(promotionId) ? promotionId : adId;
+        Long dyeTime = jsonObject.getLong("dyeTime");
+        String activationTime = DateUtils.formatDate(dyeTime * 1000, "yyyy-MM-dd HH:mm:ss");
+        String fromMedia = jsonObject.getString("from");
+        orderJson.put("stat_date", statDate);
+        orderJson.put("event", "PAY");
+        orderJson.put("event_pk", SecureUtil.md5("dianzhong_order_id:" + orderId));
+        orderJson.put("event_tag", "dianzhong_order");
+        orderJson.put("app_id", clientDomain2AppId.getOrDefault(appId, appId));
+        orderJson.put("order_no", orderId);
+        orderJson.put("platform_order_no", jsonObject.getString("outTradeNo"));
+        orderJson.put("total_fee", jsonObject.getString("discount"));
+        orderJson.put("type", jsonObject.getString("type"));
+        orderJson.put("status", jsonObject.getString("statusNotify"));
+        orderJson.put("created_at", ctime);
+        orderJson.put("pay_time", jsonObject.getLong("finishTime"));
+        orderJson.put("uid", jsonObject.getString("userId"));
+        orderJson.put("channel_id", jsonObject.getString("channelId"));
+        orderJson.put("platform", domain2Platform.getOrDefault(domain, domain));
+        orderJson.put("video_id", jsonObject.getString("sourceInfo"));
+        orderJson.put("video_detail_id", jsonObject.getString("chapterId"));
+        orderJson.put("video_name", jsonObject.getString("sourceDesc"));
+        orderJson.put("register_date", jsonObject.getString("registerDate"));
+        orderJson.put("open_id", jsonObject.getString("openId"));
+        orderJson.put("mobile_system", jsonObject.getIntValue("os") == 0 ? "Android" : "ios");
+        orderJson.put("link_id", jsonObject.getString("referralId"));
+        orderJson.put("a_id", jsonObject.getString("projectId"));
+        orderJson.put("ad_id", adId);
+        orderJson.put("person_id", jsonObject.getString("fromDrId") != null ? jsonObject.getString("fromDrId") : jsonObject.getString("kdrId"));
+        orderJson.put("scene", jsonObject.getString("scene"));
+        orderJson.put("official_account_open_id", jsonObject.getString("thirdWxId"));
+        orderJson.put("activation_time", activationTime);
+        orderJson.put("pay_type", jsonObject.getString("orderSubType"));
+        orderJson.put("media_id", media2Id.getOrDefault(fromMedia, fromMedia));
+        orderJson.put("money_benefit", jsonObject.getDouble("moneyBenefit"));
+        orderJson.put("params", jsonObject.toJSONString());
+        return orderJson;
+    }
+}

+ 6 - 5
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/ReportsAdPushServiceImpl.java

@@ -30,7 +30,7 @@ public class ReportsAdPushServiceImpl implements IReportsAdPushService {
     public static final String APP_KEY = "OUlg7WTa6UWZItfTmJw2JdQvhVI4VcRj";
 
     public static final String TEMPLATE_ID = "AAqBGlVblKabY";
-    public static final String TEMPLATE_VERSION = "1.0.12";
+    public static final String TEMPLATE_VERSION = "1.0.13";
     @Autowired
     ReportsAdPushMapper reportsPushMapper;
 
@@ -56,10 +56,10 @@ public class ReportsAdPushServiceImpl implements IReportsAdPushService {
     public void test() {
         List<String> userIds = Arrays.asList(
                 "44fbaed6" //zhaotx
-//                ,"ebeeced9" //yumeng
-//                ,"58e7a98a"  //xsq
-//                ,"2ga9669f" //angaoqi
-//                ,"43gb7fbc" //huangpingkang
+                ,"ebeeced9" //yumeng
+                ,"58e7a98a"  //xsq
+                ,"2ga9669f" //angaoqi
+                ,"43gb7fbc" //huangpingkang
         );
         send(userIds);
     }
@@ -88,6 +88,7 @@ public class ReportsAdPushServiceImpl implements IReportsAdPushService {
 
         List<Pair<String, String>> columns = Arrays.asList(
                 new Pair<>("cost_amount", "消耗金额"),
+                new Pair<>("real_cost_amount", "折后消耗"),
                 new Pair<>("end_amount", "结算金额"),
                 new Pair<>("pay_amount", "充值金额"),
                 new Pair<>("share_iaa_amount", "广告预估收入"),

+ 2 - 1
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/ReportsByBusinessPushServiceImpl.java

@@ -35,7 +35,7 @@ public class ReportsByBusinessPushServiceImpl implements IReportsByBusinessPushS
     @Autowired
     ReportsAdPushMapper reportsPushMapper;
 
-    private static final String TEMPLATE_VERSION = "1.0.2";
+    private static final String TEMPLATE_VERSION = "1.0.3";
     private static final String TEMPLATE_ID = "AAq4oeDXECopo";
 
 
@@ -103,6 +103,7 @@ public class ReportsByBusinessPushServiceImpl implements IReportsByBusinessPushS
         String updateTime = String.valueOf(todayData.get("update_time"));
         List<Pair<String, String>> columns = Arrays.asList(
                 new Pair<>("cost_amount", "消耗金额"),
+                new Pair<>("real_cost_amount", "折后消耗"),
                 new Pair<>("end_amount", "结算金额"),
                 new Pair<>("pay_amount", "充值金额"),
                 new Pair<>("iaa_amount", "广告预估收入"),

+ 75 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/utils/DateUtils.java

@@ -185,4 +185,79 @@ public class DateUtils {
         return days;
     }
 
+    public static String getQueryStartTime(String td, String format, boolean isRecover) {
+        String today = getToday();
+        if (isRecover) {
+            return transformFormat(td + " 00:00:00", "yyyy-MM-dd HH:mm:ss", format);
+        } else if (today.equals(td)) {
+            String beforeDate = dateAddByType(new Date(), -120, Calendar.MINUTE, "yyyy-MM-dd");
+            if (beforeDate.compareTo(today) < 0) {
+                return transformFormat(today + " 00:00:00", "yyyy-MM-dd HH:mm:ss", format);
+            } else {
+                return dateAddByType(new Date(), -120, Calendar.MINUTE, format);
+            }
+        } else if (today.compareTo(td) > 0) {
+            return transformFormat(td + " 22:00:00", "yyyy-MM-dd HH:mm:ss", format);
+        } else {
+            return transformFormat(td + " 00:00:00", "yyyy-MM-dd HH:mm:ss", format);
+        }
+    }
+
+    public static String getQueryEndTime(String td, String format, boolean isRecover) {
+        String today = getToday();
+        if (isRecover) {
+            return transformFormat(td + " 23:59:59", "yyyy-MM-dd HH:mm:ss", format);
+        } else if (today.equals(td)) {
+            return formatDate(new Date(), format);
+        } else {
+            return transformFormat(td + " 23:59:59", "yyyy-MM-dd HH:mm:ss", format);
+        }
+    }
+
+    public static String getToday() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        Date date = new Date();
+        return format.format(date);
+    }
+
+    public static String formatDate(Long timestamp, String formatPattern) {
+        try {
+            return formatDate(new Date(timestamp), formatPattern);
+        }catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static String formatDate(Date date, String formatPattern) {
+        SimpleDateFormat format = new SimpleDateFormat(formatPattern);
+        return format.format(date);
+    }
+
+    public static String transformFormat(String date, String fromPattern, String toFormat) {
+        if (fromPattern.equals(toFormat)) {
+            return date;
+        }
+        SimpleDateFormat format1 = new SimpleDateFormat(fromPattern);
+        SimpleDateFormat format2 = new SimpleDateFormat(toFormat);
+        try {
+            return format2.format(format1.parse(date));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static String dateAddByType(Date targetDay, int index, int calendarField, String format) {
+        String res;
+        try {
+            SimpleDateFormat smp = new SimpleDateFormat(format);
+            Calendar ca = Calendar.getInstance();
+            ca.setTime(targetDay);
+            ca.add(calendarField, index);
+            res = smp.format(ca.getTime());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return res;
+    }
+
 }

+ 42 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/utils/FieldsConfig.java

@@ -44,6 +44,21 @@ public class FieldsConfig {
 
     }
 
+    public static JSONArray getMaterialDailyDimensions() {
+        JSONArray dimensions = new JSONArray();
+        dimensions.add("stat_time_day");
+        dimensions.add("cdp_project_id");
+        dimensions.add("cdp_project_name");
+        dimensions.add("cdp_promotion_id");
+        dimensions.add("cdp_promotion_name");
+        dimensions.add("material_id");
+        dimensions.add("image_mode");
+        dimensions.add("ad_platform_material_name");
+        dimensions.add("ad_platform_material_content");
+        return dimensions;
+
+    }
+
     public static JSONArray getMetrics() {
         JSONArray metricslds = new JSONArray();
         metricslds.add("stat_pay_amount");
@@ -72,6 +87,33 @@ public class FieldsConfig {
 
     }
 
+    public static JSONArray getMaterialMetrics() {
+        JSONArray metricslds = new JSONArray();
+        metricslds.add("stat_pay_amount");
+        metricslds.add("stat_cost");
+        metricslds.add("active");
+        metricslds.add("download_finish_cnt");
+        metricslds.add("attribution_next_day_open_cnt");
+        metricslds.add("game_addiction");
+        metricslds.add("attribution_game_in_app_ltv_1day");
+        metricslds.add("attribution_deep_convert_cnt");
+        metricslds.add("game_pay_count");
+        metricslds.add("convert_cnt");
+        metricslds.add("show_cnt");
+        metricslds.add("active_pay");
+        metricslds.add("click_cnt");
+        metricslds.add("click_start_cnt");
+        metricslds.add("attribution_convert_cnt");
+        metricslds.add("deep_convert_cnt");
+        metricslds.add("valid_play");
+        metricslds.add("attribution_billing_game_in_app_ltv_1day");
+        metricslds.add("attribution_micro_game_0d_ltv");
+        metricslds.add("attribution_micro_game_3d_ltv");
+        metricslds.add("attribution_micro_game_7d_ltv");
+        return metricslds;
+
+    }
+
     public static JSONArray getProductMetrics() {
         JSONArray metricslds = new JSONArray();
         metricslds.add("stat_cost");

+ 1 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AdminAdvertiserListJob.java

@@ -45,6 +45,7 @@ public class AdminAdvertiserListJob {
                 JSONObject totalJson = adminAdvertiserListService.getBytedanceAccountListTotal(advertiserId, advertiserId, accessToken, 1, pageSize);
                 if (!Check.isNull(totalJson)) {
                     Integer totalPage = totalJson.getInteger("totalPage");
+                    log.info("管家账户ID:{},账户总数:{}", advertiserId, totalPage);
                     if (totalPage != 0) {
                         JSONObject result = adminAdvertiserListService.bytedanceAdvertiserThreadPool(totalPage, pageSize, advertiserId, advertiserId, accessToken);
                         log.info("字节多线程获取账户返回结果:{}", result);

+ 8 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMiniAppJob.java

@@ -26,4 +26,12 @@ public class BytedanceMiniAppJob {
         }
     }
 
+    @XxlJob("miniAppAdPlacement")
+    public void miniAppAdPlacement() throws Exception {
+        List<String> appIds = bytedanceMiniAppService.getAllAppIds();
+        for (String appId : appIds) {
+            bytedanceMiniAppService.getAdPlacement(appId);
+        }
+    }
+
 }

+ 23 - 7
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedancePromoterReportJob.java

@@ -1,6 +1,7 @@
 package cn.com.ctop.job.bytedance.handler;
 
 
+import cn.com.ctop.job.bytedance.data.service.IBytedanceMaterialReportService;
 import cn.com.ctop.job.bytedance.data.service.IBytedanceProductReportService;
 import cn.com.ctop.job.bytedance.data.service.IBytedancePromoterReportService;
 import cn.com.ctop.job.bytedance.data.service.IChannelService;
@@ -28,20 +29,14 @@ import java.util.concurrent.Executors;
 public class BytedancePromoterReportJob {
     @Autowired
     private IBytedanceProductReportService productReportService;
-
     @Autowired
     private IBytedancePromoterReportService promoterReportService;
     @Autowired
-    private IChannelService channelService;
+    private IBytedanceMaterialReportService bytedanceMaterialReportService;
 
     private static ExecutorService dailyExecutorService = Executors.newFixedThreadPool(10);
     private static ExecutorService hourExecutorService = Executors.newFixedThreadPool(4);
-
-    private static ExecutorService dailyRetrExecutorService = Executors.newFixedThreadPool(2);
-    private static ExecutorService hourRetrExecutorService = Executors.newFixedThreadPool(2);
-
     private static ExecutorService productDailyExecutor = Executors.newFixedThreadPool(2);
-    private static ExecutorService productDailyRetrExecutor = Executors.newFixedThreadPool(2);
 
 
     @XxlJob("yesHourPromoterReport")
@@ -134,6 +129,27 @@ public class BytedancePromoterReportJob {
         });
     }
 
+    @XxlJob("yesMaterialReportDaily")
+    public void yesMaterialReportDaily() throws Exception {
+        String param = XxlJobHelper.getJobParam(); // 执行参数
+        if (Check.isNull(param)) {
+            log.error("入参为空");
+            return;
+        }
+
+        String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
+        String date = DateUtils.getAnotherDay("yyyy-MM-dd", nowDate, -1);
+        String[] s = param.split("_");
+        Long advertiserId = Long.valueOf(s[0]);
+        String accessToken = s[1];
+
+        dailyExecutorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                bytedanceMaterialReportService.getBytedanceMaterialDailyReport(advertiserId, accessToken, date, date, 1, null, 1, 0);
+            }
+        });
+    }
 
 
 }

+ 46 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceReportRetryJob.java

@@ -1,6 +1,7 @@
 package cn.com.ctop.job.bytedance.handler;
 
 
+import cn.com.ctop.job.bytedance.config.DianZhongConfig;
 import cn.com.ctop.job.bytedance.data.enums.AccountTypeEnum;
 import cn.com.ctop.job.bytedance.data.service.*;
 import cn.com.ctop.job.bytedance.data.utils.Check;
@@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -44,6 +46,15 @@ public class BytedanceReportRetryJob {
     @Autowired
     private IBytedanceXingTuService bytedanceXingTuService;
 
+    @Autowired
+    private IBytedanceMaterialReportService bytedanceMaterialReportService;
+
+    @Autowired
+    private IDianZhongService dianZhongService;
+
+    @Resource
+    private DianZhongConfig dianZhongConfig;
+
 
     private static ExecutorService hourAccountRetrExecutorService = Executors.newFixedThreadPool(2);
     private static ExecutorService dailyAccountRetrExecutorService = Executors.newFixedThreadPool(2);
@@ -133,6 +144,15 @@ public class BytedanceReportRetryJob {
                             byteDanceFlowDetailsReportService.getBytedanceFlowDetailsDailyReport(advertiserId, accessToken, AccountTypeEnum.AD.getValue(), startDate, endDate, 1, id);
                         }
                     });
+                } else if ("material".equals(dataDimension)) {
+                    productDailyRetrExecutor.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (!Check.isNull(accessToken)) {
+                                bytedanceMaterialReportService.getBytedanceMaterialDailyReport(advertiserId, accessToken, startDate, endDate, 1, id, null, isSend);
+                            }
+                        }
+                    });
                 }
 
 
@@ -233,6 +253,32 @@ public class BytedanceReportRetryJob {
             log.info("巨量星图重试列表为空");
         }
 
+        List<JSONObject> dzRetry = dianZhongService.getDZRetry();
+        if (!Check.isNull(dzRetry)) {
+            for (int i = 0; i < dzRetry.size(); i++) {
+                JSONObject jsonObject = dzRetry.get(i);
+                Long id = jsonObject.getLong("id");
+                String clientId = jsonObject.getString("advertiserId");
+                String startDate = jsonObject.getString("startDate");
+                String endDate = jsonObject.getString("endDate");
+                String dataDimension = jsonObject.getString("dataDimension");
+                String dataType = jsonObject.getString("dataType");
+                String token = dianZhongConfig.getToken(clientId);
+                if ("dianzhong_url".equals(dataDimension)) {
+                    changduExecutorService.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (!Check.isNull(token)) {
+                                dianZhongService.getDownloadUrl(dataType, clientId, token, startDate, endDate, id, false);
+                            }
+                        }
+                    });
+                }
+            }
+        } else {
+            log.info("点众重试列表为空");
+        }
+
     }
 
 

+ 80 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/CsjResoureJob.java

@@ -0,0 +1,80 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumResourceInfo;
+import cn.com.ctop.job.bytedance.data.entity.CsjAlbumSeqResourceInfo;
+import cn.com.ctop.job.bytedance.data.service.ICsjResourceService;
+import cn.com.ctop.job.bytedance.data.utils.Check;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Component
+public class CsjResoureJob {
+    @Autowired
+    ICsjResourceService csjResourceService;
+
+    private static ExecutorService linkRefreshExecutorService = Executors.newFixedThreadPool(5);
+
+    @XxlJob("csjResourceOssJob")
+    public void csjResourceOssJob(){
+
+        List<CsjAlbumResourceInfo> list = csjResourceService.albumList();
+        if (list == null || list.isEmpty()) {
+            log.info("没有需要处理的资源");
+            return; // 没有需要处理的资源
+        }
+        int count = 0;
+        for (CsjAlbumResourceInfo album : list) {
+            if (isDone(album)) {
+                log.info("资源已被处理,跳过: " + album.getAlbumId());
+                continue;
+            }
+//            if (++count > 10){
+//                break; //剧目数限制
+//            }
+            linkRefreshExecutorService.submit(() -> {
+                try {
+                    String result = csjResourceService.run(album);
+                    if (result != null && !result.isEmpty()) {
+                        log.error("处理资源失败: " + result);
+                    } else {
+                        log.info("处理资源成功: " + album.getAlbumId());
+                    }
+                } catch (Exception e) {
+                    log.error("处理资源时发生异常: " + e.getMessage(), e);
+                }
+            });
+        }
+        log.info("本次上传剧目数:{}", count);
+    }
+
+
+    /**
+     * 是否已经处理完成
+     */
+    private boolean isDone(CsjAlbumResourceInfo album){
+        if (Check.isNull(album.getOssCoverImg())){
+            return false;
+        }
+        if (album.getSeqList() == null){ //todo 没有分集,是否为空
+            log.error("*资源没有分集信息: " + album.getAlbumId());
+            return false;
+        }
+        for (CsjAlbumSeqResourceInfo seq : album.getSeqList()){
+            if (Check.isNull(seq.getOssSeqVideo())){
+                return false;
+            }
+            if (Check.isNull(seq.getOssSeqImg())){
+                return false;
+            }
+        }
+        return true;
+    }
+
+}

+ 55 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/DianZhongJob.java

@@ -0,0 +1,55 @@
+package cn.com.ctop.job.bytedance.handler;
+
+
+import cn.com.ctop.job.bytedance.config.DianZhongConfig;
+import cn.com.ctop.job.bytedance.data.service.IDianZhongService;
+import cn.com.ctop.job.bytedance.data.utils.DateUtils;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@Component
+public class DianZhongJob {
+    @Autowired
+    private IDianZhongService dianZhongService;
+
+    @Resource
+    private DianZhongConfig dianZhongConfig;
+
+    /**
+     * 获取点众IAP数据url
+     */
+    @XxlJob("dzDownloadUrl")
+    public void dzDownloadUrl() {
+        List<DianZhongConfig.DZConfig> dzConfig = dianZhongConfig.getDzConfig();
+        for (DianZhongConfig.DZConfig config : dzConfig) {
+            if ("iaa".equals(config.getType())) {
+                continue;
+            }
+            String statDate = DateUtils.dateAddByType(new Date(), -10, Calendar.MINUTE, "yyyy-MM-dd");
+            String clientId = config.getClientId();
+            String token = config.getToken();
+            String queryStartTime = DateUtils.getQueryStartTime(statDate, "yyyy-MM-dd HH:mm:ss", false);
+            String queryEndTime = DateUtils.getQueryEndTime(statDate, "yyyy-MM-dd HH:mm:ss", false);
+            dianZhongService.getDownloadUrl("user", clientId, token, queryStartTime, queryEndTime, null, true);
+            dianZhongService.getDownloadUrl("order", clientId, token, queryStartTime, queryEndTime, null, true);
+        }
+    }
+
+    /**
+     * 点众IAP数据下载
+     */
+    @XxlJob("dzUrlData")
+    public void dzUrlData() {
+        String statDate = DateUtils.dateAddByType(new Date(), -10, Calendar.MINUTE, "yyyy-MM-dd");
+        dianZhongService.getUrlData(statDate);
+    }
+
+}

+ 24 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/OssProperties.java

@@ -0,0 +1,24 @@
+package cn.com.ctop.job.bytedance.utils;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+/**
+ * oss 配置
+ */
+@Lazy
+@Setter
+@Getter
+@Component
+@ConfigurationProperties(prefix = "playlet.oss")
+public class OssProperties {
+    private String endpoint;
+    private String accessKey;
+    private String accessSecret;
+    private String bucketName;
+    private String csjDomain;
+    private String csjFileDir;
+}

+ 108 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/OssUtil.java

@@ -0,0 +1,108 @@
+package cn.com.ctop.job.bytedance.utils;
+import com.aliyun.oss.ClientException;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.OSSException;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.aliyun.oss.model.PutObjectRequest;
+import com.aliyun.oss.model.PutObjectResult;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.net.HttpURLConnection;
+
+@Lazy
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class OssUtil {
+    @Getter
+    private final OssProperties ossProperties;
+
+    public void uploadFromUrl(String objectKey, String fileUrl) throws Exception {
+        // 创建OSS客户端
+        OSS ossClient = new OSSClientBuilder().build(ossProperties.getEndpoint(), ossProperties.getAccessKey(), ossProperties.getAccessSecret());
+
+        HttpURLConnection conn = null;
+        InputStream inputStream = null;
+
+        try {
+//            inputStream = new URL(fileUrl).openStream();
+//            // 创建PutObjectRequest对象。
+//            PutObjectRequest putObjectRequest = new PutObjectRequest(ossProperties.getBucketName(), objectKey, inputStream);
+//            // 创建PutObject请求。
+//            PutObjectResult result = ossClient.putObject(putObjectRequest);
+//            // 打开HTTP连接
+            URL url = new URL(fileUrl);
+            conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("GET");
+            conn.setConnectTimeout(5000);  // 5秒连接超时
+            conn.setReadTimeout(30000);    // 30秒读取超时
+
+            // 获取输入流和元数据
+            inputStream = conn.getInputStream();
+            int contentLength = conn.getContentLength();
+            String contentType = conn.getContentType();
+
+            // 创建OSS元数据
+            ObjectMetadata metadata = new ObjectMetadata();
+            if (contentLength > 0) {
+                metadata.setContentLength(contentLength);
+            }
+            if (contentType != null) {
+                metadata.setContentType(contentType);
+            }
+
+            // 创建上传请求
+            PutObjectRequest putRequest = new PutObjectRequest(
+                    ossProperties.getBucketName(),
+                    objectKey,
+                    inputStream,
+                    metadata
+            );
+
+            // 执行上传
+            PutObjectResult result = ossClient.putObject(putRequest);
+
+        } catch (OSSException oe) {
+            System.out.println("Caught an OSSException, which means your request made it to OSS, "
+                    + "but was rejected with an error response for some reason.");
+            System.out.println("Error Message:" + oe.getErrorMessage());
+            System.out.println("Error Code:" + oe.getErrorCode());
+            System.out.println("Request ID:" + oe.getRequestId());
+            System.out.println("Host ID:" + oe.getHostId());
+            throw oe;
+        } catch (ClientException ce) {
+            System.out.println("Caught an ClientException, which means the client encountered "
+                    + "a serious internal problem while trying to communicate with OSS, "
+                    + "such as not being able to access the network.");
+            System.out.println("Error Message:" + ce.getMessage());
+            throw ce;
+        } finally {
+            // 关闭资源
+            if (inputStream != null) inputStream.close();
+            if (conn != null) conn.disconnect();
+            if (ossClient != null) ossClient.shutdown();
+        }
+    }
+
+    public void test() {
+        try {
+            String fileUrl = "https://p3-developer-sign.bytemaimg.com/tos-cn-i-o9yqv5mzf9/63af95e356f4f348b809b5b4a8f7462b~tplv-ke512zj2cu-jpg.image?lk3s=6ecb03b0&x-expires=1755601981&x-signature=L7y5AuCHlmkrtYyMybynp558wM8%3D";
+            String objectKey = "csj/test.jpg"; // OSS存储路径
+
+            uploadFromUrl(objectKey, fileUrl);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 11 - 1
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/doris/sink/DorisMultiTableStreamLoadManager.java

@@ -5,11 +5,11 @@ import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
 
 import javax.annotation.PreDestroy;
 import java.util.Collection;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 
 @Slf4j
 public class DorisMultiTableStreamLoadManager {
@@ -48,5 +48,15 @@ public class DorisMultiTableStreamLoadManager {
         log.info("Shutting down DorisMultiTableStreamLoadManager");
         bufferManagers.values().forEach(TableBufferManager::flushNow);
         uploaderExecutor.shutdown();
+        try {
+            if (!uploaderExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
+                log.info("doris stream load 任务未完成,强制关闭线程池...");
+                uploaderExecutor.shutdownNow();
+            }
+        } catch (InterruptedException e) {
+            uploaderExecutor.shutdownNow();
+            Thread.currentThread().interrupt();
+        }
+        log.info("doris stream load 线程池已关闭");
     }
 }

+ 19 - 0
job-bytedance/src/main/resources/application.yml

@@ -180,5 +180,24 @@ api:
   bytedance:
     api-prefix: https://ad.oceanengine.com/open_api
 
+playlet:
+  oss:
+    accessKey: LTAI5tAZjbTv3PtTMZHFAhkb
+    accessSecret: DK3uoycrIiUxJSol3gMNWmcOyzJqU8
+    endpoint: oss-cn-beijing-internal.aliyuncs.com
+#    endpoint: oss-cn-beijing.aliyuncs.com
+    bucketName: short-theatre-hr
+    csjDomain: https://oss.artlinkworld.cn/
+    csjFileDir: csj/
 
+dianzhong:
+  client:
+    dzConfig[0]:
+      clientId: 10003129
+      token: ckogrgCE4PEDxT1oL5
+      type: iap
+    dzConfig[1]:
+      clientId: 10004501
+      token: HgmmEQM4ddcLQ8mn5i
+      type: iaa