فهرست منبع

快手报表获取

yumeng 1 روز پیش
والد
کامیت
96a0305b85
21فایلهای تغییر یافته به همراه881 افزوده شده و 39 حذف شده
  1. 5 0
      job-kuaishou/pom.xml
  2. 43 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/config/RedissonConfig.java
  3. 20 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/controller/KuaiShouController.java
  4. 12 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/constant/KuaishouLinkConstants.java
  5. 40 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/KuaishouAdvertiserFund.java
  6. 2 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/KuaishouDailyFlows.java
  7. 189 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/KuaishouMaterialReportDaily.java
  8. 3 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/KuaiShouAccountReportMapper.java
  9. 11 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/KuaiShouMaterialReportMapper.java
  10. 19 3
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/xml/KuaiShouAccountReportMapper.xml
  11. 79 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/xml/KuaiShouMaterialReportMapper.xml
  12. 5 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/IKuaiShouAccountReportService.java
  13. 8 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/IKuaiShouMaterialReportService.java
  14. 77 23
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/KuaiShouAccountReportServiceImpl.java
  15. 152 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/KuaiShouMaterialReportServiceImpl.java
  16. 15 12
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/KuaiShouRetryReportServiceImpl.java
  17. 88 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/utils/RateLimitUtil.java
  18. 20 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouAccountReportJob.java
  19. 69 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouMaterialReportJob.java
  20. 23 0
      job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouRetryReportJob.java
  21. 1 1
      job-kuaishou/src/main/resources/application.yml

+ 5 - 0
job-kuaishou/pom.xml

@@ -172,6 +172,11 @@
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <version>3.36.0</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-pool2</artifactId>
             <version>2.6.2</version>

+ 43 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/config/RedissonConfig.java

@@ -0,0 +1,43 @@
+package cn.com.ctop.job.kuaishou.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.redisson.config.SingleServerConfig;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Redisson 配置(供 RateLimitUtil 分布式频控使用)
+ * 密码沿用 spring.redis.password:阿里云 Redis 自定义账号认证下该值为
+ * "user:password" 一体格式,Redisson 单参 AUTH 与 Lettuce 行为一致
+ */
+@Slf4j
+@Configuration
+public class RedissonConfig {
+
+    @Value("${spring.redis.host}")
+    private String host;
+
+    @Value("${spring.redis.port}")
+    private int port;
+
+    @Value("${spring.redis.database}")
+    private int database;
+
+    @Value("${spring.redis.password}")
+    private String password;
+
+    @Bean(destroyMethod = "shutdown")
+    public RedissonClient redissonClient() {
+        Config config = new Config();
+        SingleServerConfig serverConfig = config.useSingleServer()
+                .setAddress("redis://" + host + ":" + port)
+                .setDatabase(database)
+                .setPassword(password);
+        log.info("Redisson 初始化完成, address: redis://{}:{}, database: {}", host, port, database);
+        return Redisson.create(config);
+    }
+}

+ 20 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/controller/KuaiShouController.java

@@ -3,6 +3,7 @@ package cn.com.ctop.job.kuaishou.controller;
 import cn.com.ctop.job.kuaishou.data.mapper.KuaiShouAccountReportMapper;
 import cn.com.ctop.job.kuaishou.data.service.IKuaiShouAccountReportService;
 import cn.com.ctop.job.kuaishou.data.service.IKuaiShouGroupReportService;
+import cn.com.ctop.job.kuaishou.data.service.IKuaiShouMaterialReportService;
 import cn.com.ctop.job.kuaishou.data.service.IKuaiShouRefreshTokenService;
 import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
 import com.alibaba.fastjson.JSONObject;
@@ -41,6 +42,9 @@ public class KuaiShouController {
 
     @Autowired
     private IKuaiShouAccountReportService accountReportService;
+
+    @Autowired
+    private IKuaiShouMaterialReportService materialReportService;
     static ExecutorService executorService = Executors.newFixedThreadPool(5);
 
     @GetMapping("/queryGroupReportHourly")
@@ -85,6 +89,22 @@ public class KuaiShouController {
 
     }
 
+    @GetMapping("/queryMaterialReportDaily")
+    public void queryMaterialReportDaily(String accessToken, Long advertiserId, String startDate, String endDate) {
+        materialReportService.queryMaterialReportDaily(accessToken, advertiserId, startDate, endDate, 1);
+    }
+
+    @GetMapping("/queryAccountFund")
+    public void queryAccountFund(String accessToken, Long advertiserId) {
+        String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
+        accountReportService.queryAccountFund(accessToken, advertiserId, nowDate, null, 2);
+    }
+
+    @GetMapping("/queryAccountDailyFlows")
+    public void queryAccountDailyFlowsSingle(String accessToken, Long advertiserId, String startDate, String endDate) {
+        accountReportService.queryAccountDailyFlows(accessToken, advertiserId, startDate, endDate, 1, 1, null, 2, 1);
+    }
+
     @GetMapping("/groupList")
     public void groupList(String startDate, String endDate) {
         Integer intStartDate = Integer.valueOf(startDate.replace("-", ""));

+ 12 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/constant/KuaishouLinkConstants.java

@@ -12,6 +12,18 @@ public class KuaishouLinkConstants {
      * 广告组数据 POST
      */
     public static final String V1_GROUP_REPORT = "/rest/openapi/v1/report/unit_report";
+    /**
+     * 素材报表数据 POST
+     */
+    public static final String V1_MATERIAL_REPORT = "/rest/openapi/v1/report/material_report";
+    /**
+     * 广告主账户余额 POST
+     */
+    public static final String V1_ADVERTISER_FUND_GET = "/rest/openapi/v1/advertiser/fund/get";
+    /**
+     * 广告主账户流水 POST
+     */
+    public static final String V1_ADVERTISER_FUND_DAILY_FLOWS = "/rest/openapi/v1/advertiser/fund/daily_flows";
     public static final String DRAMA_AD_REPORT_DETAIL = "/rest/openapi/gw/dsp/series/report/queryAdDetail";
     public static final String DRAMA_ORDER_DETAIL = "/rest/openapi/gw/dsp/series/report/queryOrderDetail";
     public static final String DRAMA_SALER_ORDER_DETAIL = "/rest/openapi/gw/dsp/series/report/querySalerOrderDetail";

+ 40 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/KuaishouAdvertiserFund.java

@@ -0,0 +1,40 @@
+package cn.com.ctop.job.kuaishou.data.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 快手广告主账户资金余额快照(/rest/openapi/v1/advertiser/fund/get)
+ */
+@Data
+public class KuaishouAdvertiserFund implements Serializable {
+
+    /** 数据日期 yyyyMMdd(当日快照,重复拉取覆盖刷新) */
+    private Integer statDate;
+
+    /** 广告主账户ID */
+    private Long advertiserId;
+
+    /** 账户总余额(元) */
+    private BigDecimal balance;
+
+    /** 充值余额(元) */
+    private BigDecimal rechargeBalance;
+
+    /** 框返余额(元) */
+    private BigDecimal contractRebate;
+
+    /** 激励余额(元) */
+    private BigDecimal directRebate;
+
+    /** 延期余额(元) */
+    private BigDecimal extendedBalance;
+
+    /** 共享钱包总余额(元) */
+    private BigDecimal totalSharedWalletBalance;
+
+    /** 年框共享钱包总余额(元) */
+    private BigDecimal totalFrameSharedWalletBalance;
+}

+ 2 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/KuaishouDailyFlows.java

@@ -29,4 +29,6 @@ public class KuaishouDailyFlows implements Serializable {
     private BigDecimal dailyShareCharge;
     private BigDecimal shareRealCharge;
     private BigDecimal shareCreditCharge;
+    /** 年框共享钱包花费(元) */
+    private BigDecimal frameShareWalletCharge;
 }

+ 189 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/KuaishouMaterialReportDaily.java

@@ -0,0 +1,189 @@
+package cn.com.ctop.job.kuaishou.data.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 快手素材日报表(media_kuaishou_material_report_daily)
+ * 指标字段与账户日报(KuaishouAccountReportDaily)保持一致,
+ * 额外保留素材报表维度字段(photo_id/pic_id 等)
+ */
+@Data
+public class KuaishouMaterialReportDaily implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 广告主id
+     */
+    private Long advertiserId;
+
+
+    /**
+     * 数据日期,格式:YYYYMMDD
+     */
+    private Integer statDate;
+
+
+    /**
+     * 视频素材id(视频素材行有值,其余为0)
+     */
+    private Long photoId = 0L;
+
+
+    /**
+     * 视频素材签名
+     */
+    private String photoSignature = "";
+
+
+    /**
+     * 视频素材url
+     */
+    private String photoUrl;
+
+
+    /**
+     * 封面url
+     */
+    private String coverUrl;
+
+
+    /**
+     * 贴纸url
+     */
+    private String stickyUrl;
+
+
+    /**
+     * 图片素材url列表(JSON数组字符串)
+     */
+    private String imageUrls;
+
+
+    /**
+     * 图片素材id(图片素材行有值,其余为0)
+     */
+    private Long picId = 0L;
+
+
+    /**
+     * 图片素材签名
+     */
+    private String picSignature = "";
+
+
+    /**
+     * 广告场景
+     */
+    private String adScene = "";
+
+
+    /**
+     * 是否AIGC素材
+     */
+    private String aigcMaterial;
+
+
+    /**
+     * 花费(元)
+     */
+    private BigDecimal charge;
+
+    /**
+     * 行为数
+     */
+    private Long bclick;
+
+    /**
+     * 应用下载数据-激活数
+     */
+    private Long activation;
+
+    /**
+     * 应用下载数据-首日付费次数
+     */
+    private Long eventPayFirstDay;
+
+    /**
+     * 应用下载数据-首日付费金额
+     */
+    private BigDecimal eventPayPurchaseAmountFirstDay;
+
+    /**
+     * 应用下载数据-付费次数
+     */
+    private Long eventPay;
+
+    /**
+     * 应用下载数据-付费金额
+     */
+    private BigDecimal eventPayPurchaseAmount;
+
+    /**
+     * 应用下载数据-注册数
+     */
+    private Long eventRegister;
+
+    /**
+     * 新增付费人数
+     */
+    private BigDecimal eventNewUserPay;
+
+    /**
+     * 关键行为
+     */
+    private Long keyAction;
+
+    /**
+     * 转化数(回传时间)
+     */
+    private Long conversionNum;
+
+    /**
+     * 转化数(计费时间)
+     */
+    private Long conversionNumByImpression7d;
+
+    /**
+     * 转化成本(回传时间归因)
+     */
+    private BigDecimal conversionNumCost;
+
+    /**
+     * 深度转化数(回传时间归因)
+     */
+    private Long deepConversionNum;
+
+    /**
+     * 深度转化数(7日曝光时间归因)
+     */
+    private Long deepConversionNumByImpression7d;
+
+    /**
+     * 播放完成
+     */
+    private Long playedEnd;
+
+    /**
+     * 有效播放数
+     */
+    private Long playedThreeSeconds;
+
+    /**
+     * 广告曝光
+     */
+    private BigDecimal adShow;
+
+    /**
+     * IAA广告变现LTV
+     */
+    private BigDecimal minigameIaaPurchaseAmount;
+
+    /**
+     * 当日广告LTV
+     */
+    private BigDecimal minigameIaaPurchaseAmountFirstDay;
+}

+ 3 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/KuaiShouAccountReportMapper.java

@@ -2,6 +2,7 @@ package cn.com.ctop.job.kuaishou.data.mapper;
 
 import cn.com.ctop.job.kuaishou.data.entity.KuaishouAccountReportDaily;
 import cn.com.ctop.job.kuaishou.data.entity.KuaishouAccountReportHour;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdvertiserFund;
 import cn.com.ctop.job.kuaishou.data.entity.KuaishouDailyFlows;
 import com.alibaba.fastjson.JSONObject;
 import org.apache.ibatis.annotations.Param;
@@ -19,6 +20,8 @@ public interface KuaiShouAccountReportMapper {
 
     void replaceKuaiShouDailyFlows(List<KuaishouDailyFlows> addList);
 
+    void replaceKuaiShouAdvertiserFund(@Param("adds") List<KuaishouAdvertiserFund> addList);
+
     List<JSONObject> queryCostAccount(@Param("startDate")Integer startDate,@Param("endDate")Integer endDate);
 
     String getTokenByAdvertiserId(@Param("advertiserId") Long advertiserId);

+ 11 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/KuaiShouMaterialReportMapper.java

@@ -0,0 +1,11 @@
+package cn.com.ctop.job.kuaishou.data.mapper;
+
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouMaterialReportDaily;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface KuaiShouMaterialReportMapper {
+
+    void replaceBatcKuaiShouMaterialReportDaily(@Param("adds") List<KuaishouMaterialReportDaily> addList);
+}

+ 19 - 3
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/xml/KuaiShouAccountReportMapper.xml

@@ -120,12 +120,13 @@
 
 
     <insert id="replaceKuaiShouDailyFlows">
-        INSERT INTO media_api.kuaishou_advertiser_daily_flows (
+        replace into media_kuaishou_advertiser_daily_flows (
         stat_date, balance, advertiser_id, daily_charge, daily_common_charge,
         real_charged, extended_charged, contract_rebate_real_charged, direct_rebate_real_charged,
         daily_transfer_in, real_recharged, contract_rebate_real_recharged, direct_rebate_real_recharged,
         daily_transfer_out, order_total_charged, order_real_charged, order_extended_charged,
-        order_contract_charged, order_direct_charged, daily_share_charge, share_real_charge, share_credit_charge
+        order_contract_charged, order_direct_charged, daily_share_charge, share_real_charge, share_credit_charge,
+        frame_share_wallet_charge
         )
         VALUES
         <foreach collection="list" item="item" separator=",">
@@ -134,7 +135,22 @@
             #{item.realCharged}, #{item.extendedCharged}, #{item.contractRebateRealCharged}, #{item.directRebateRealCharged},
             #{item.dailyTransferIn}, #{item.realRecharged}, #{item.contractRebateRealRecharged}, #{item.directRebateRealRecharged},
             #{item.dailyTransferOut}, #{item.orderTotalCharged}, #{item.orderRealCharged}, #{item.orderExtendedCharged},
-            #{item.orderContractCharged}, #{item.orderDirectCharged}, #{item.dailyShareCharge}, #{item.shareRealCharge}, #{item.shareCreditCharge}
+            #{item.orderContractCharged}, #{item.orderDirectCharged}, #{item.dailyShareCharge}, #{item.shareRealCharge}, #{item.shareCreditCharge},
+            #{item.frameShareWalletCharge}
+            )
+        </foreach>
+    </insert>
+
+    <insert id="replaceKuaiShouAdvertiserFund">
+        replace into media_kuaishou_advertiser_fund (
+        stat_date, advertiser_id, balance, recharge_balance, contract_rebate, direct_rebate,
+        extended_balance, total_shared_wallet_balance, total_frame_shared_wallet_balance
+        )
+        VALUES
+        <foreach collection="adds" item="item" separator=",">
+            (
+            #{item.statDate}, #{item.advertiserId}, #{item.balance}, #{item.rechargeBalance}, #{item.contractRebate}, #{item.directRebate},
+            #{item.extendedBalance}, #{item.totalSharedWalletBalance}, #{item.totalFrameSharedWalletBalance}
             )
         </foreach>
     </insert>

+ 79 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/xml/KuaiShouMaterialReportMapper.xml

@@ -0,0 +1,79 @@
+<?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.kuaishou.data.mapper.KuaiShouMaterialReportMapper">
+
+    <insert id="replaceBatcKuaiShouMaterialReportDaily">
+        replace into media_kuaishou_material_report_daily
+        (
+        advertiser_id,
+        stat_date,
+        photo_id,
+        photo_signature,
+        photo_url,
+        cover_url,
+        sticky_url,
+        image_urls,
+        pic_id,
+        pic_signature,
+        ad_scene,
+        aigc_material,
+        charge,
+        bclick,
+        activation,
+        event_pay_first_day,
+        event_pay_purchase_amount_first_day,
+        event_pay,
+        event_pay_purchase_amount,
+        event_register,
+        event_new_user_pay,
+        key_action,
+        conversion_num,
+        conversion_num_by_impression_7d,
+        conversion_num_cost,
+        deep_conversion_num,
+        deep_conversion_num_by_impression_7d,
+        played_end,
+        played_three_seconds,
+        ad_show,
+        minigame_iaa_purchase_amount,
+        minigame_iaa_purchase_amount_first_day
+        )
+        values
+        <foreach collection="adds" item="ad" separator=",">
+            (
+            #{ad.advertiserId},
+            #{ad.statDate},
+            #{ad.photoId},
+            #{ad.photoSignature},
+            #{ad.photoUrl},
+            #{ad.coverUrl},
+            #{ad.stickyUrl},
+            #{ad.imageUrls},
+            #{ad.picId},
+            #{ad.picSignature},
+            #{ad.adScene},
+            #{ad.aigcMaterial},
+            #{ad.charge},
+            #{ad.bclick},
+            #{ad.activation},
+            #{ad.eventPayFirstDay},
+            #{ad.eventPayPurchaseAmountFirstDay},
+            #{ad.eventPay},
+            #{ad.eventPayPurchaseAmount},
+            #{ad.eventRegister},
+            #{ad.eventNewUserPay},
+            #{ad.keyAction},
+            #{ad.conversionNum},
+            #{ad.conversionNumByImpression7d},
+            #{ad.conversionNumCost},
+            #{ad.deepConversionNum},
+            #{ad.deepConversionNumByImpression7d},
+            #{ad.playedEnd},
+            #{ad.playedThreeSeconds},
+            #{ad.adShow},
+            #{ad.minigameIaaPurchaseAmount},
+            #{ad.minigameIaaPurchaseAmountFirstDay}
+            )
+        </foreach>
+    </insert>
+</mapper>

+ 5 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/IKuaiShouAccountReportService.java

@@ -11,5 +11,10 @@ public interface IKuaiShouAccountReportService {
 
     void queryAccountDailyFlows(String accessToken, Long advertiserId, String startDate, String endDate, int page, Integer isLog, Long errId, Integer isSend, int retry);
 
+    /**
+     * 拉取广告主账户余额快照(当日,重复拉取覆盖刷新)
+     */
+    void queryAccountFund(String accessToken, Long advertiserId, String statDate, Long errId, Integer isSend);
+
     String getTokenByAdvertiserId(Long advertiserId);
 }

+ 8 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/IKuaiShouMaterialReportService.java

@@ -0,0 +1,8 @@
+package cn.com.ctop.job.kuaishou.data.service;
+
+public interface IKuaiShouMaterialReportService {
+
+    void queryMaterialReportDaily(String accessToken, Long advertiserId, String startDate, String endDate, int page);
+
+    void getMaterialDailyRetry(Long errorId, Long advertiserId, String accessToken, String startDate, String endDate, Integer page, Integer isSend);
+}

+ 77 - 23
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/KuaiShouAccountReportServiceImpl.java

@@ -1,7 +1,9 @@
 package cn.com.ctop.job.kuaishou.data.service.impl;
 
+import cn.com.ctop.job.kuaishou.data.constant.KuaishouLinkConstants;
 import cn.com.ctop.job.kuaishou.data.entity.KuaishouAccountReportDaily;
 import cn.com.ctop.job.kuaishou.data.entity.KuaishouAccountReportHour;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdvertiserFund;
 import cn.com.ctop.job.kuaishou.data.entity.KuaishouDailyFlows;
 import cn.com.ctop.job.kuaishou.data.mapper.KuaiShouAccountReportMapper;
 import cn.com.ctop.job.kuaishou.data.service.IKuaiShouAccountReportService;
@@ -9,6 +11,7 @@ import cn.com.ctop.job.kuaishou.data.service.IKuaiShouErrorLogService;
 import cn.com.ctop.job.kuaishou.data.utils.Check;
 import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
 import cn.com.ctop.job.kuaishou.data.utils.HttpUtils;
+import cn.com.ctop.job.kuaishou.data.utils.RateLimitUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
@@ -29,16 +32,13 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
     private IKuaiShouErrorLogService errorLogService;
     @Autowired
     private KuaiShouAccountReportMapper accountReportMapper;
+    @Autowired
+    private RateLimitUtil rateLimitUtil;
 
 
 
     @Override
     public void queryAccountReportHourly(String accessToken, Long advertiserId, String startDate, String endDate, int page) {
-        try {
-            Thread.sleep(1500);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
         String url = "https://ad.e.kuaishou.com/rest/openapi/v1/report/account_report";
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", "application/json");
@@ -54,7 +54,14 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
         param.put("temporal_granularity", "HOURLY");
         param.put("page_size", 2000);
         param.put("page", page);
-        String result = HttpUtils.httpPostRequest(url, param, headers);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
+        if (Check.isNull(result)) {
+            String errMsg = acquired ? "返回结果为空" : "频控等待超时";
+            log.error("获取快手账号时报报表异常:{},accountId:{}", errMsg, advertiserId);
+            errorLogService.addError(advertiserId, startDate, endDate, "account", "hour", errMsg, 2);
+            return;
+        }
         JSONObject resultJson = JSONObject.parseObject(result);
         Integer code = resultJson.getInteger("code");
         String message = resultJson.getString("message");
@@ -89,11 +96,6 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
 
     @Override
     public void queryAccountReportDaily(String accessToken, Long advertiserId, String startDate, String endDate, int page) {
-        try {
-            Thread.sleep(1500);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
         String url = "https://ad.e.kuaishou.com/rest/openapi/v1/report/account_report";
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", "application/json");
@@ -109,7 +111,14 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
         param.put("temporal_granularity", "DAILY");
         param.put("page_size", 2000);
         param.put("page", page);
-        String result = HttpUtils.httpPostRequest(url, param, headers);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
+        if (Check.isNull(result)) {
+            String errMsg = acquired ? "返回结果为空" : "频控等待超时";
+            log.error("获取快手账号日报报表异常:{},accountId:{}", errMsg, advertiserId);
+            errorLogService.addError(advertiserId, startDate, endDate, "account", "daily", errMsg, 2);
+            return;
+        }
         JSONObject resultJson = JSONObject.parseObject(result);
         Integer code = resultJson.getInteger("code");
         String message = resultJson.getString("message");
@@ -142,7 +151,7 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
 
     @Override
     public void queryAccountDailyFlows(String accessToken, Long advertiserId, String startDate, String endDate, int page, Integer isLog, Long errId, Integer isSend, int retry) {
-        String url = "https://ad.e.kuaishou.com/rest/openapi/v1/advertiser/fund/daily_flows";
+        String url = KuaishouLinkConstants.KS_PREFIX + KuaishouLinkConstants.V1_ADVERTISER_FUND_DAILY_FLOWS;
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", "application/json");
         headers.put("Access-Token", accessToken);
@@ -157,11 +166,13 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
         param.put("advertiser_id", advertiserId);
         param.put("page_size", pageSize);
         param.put("page", page);
-        String result = HttpUtils.httpPostRequest(url, param, headers);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
         if (Check.isNull(result)) {
-            log.error("获取快手广告账户流水信息异常:{},accountId:{} {}~{}", "返回结果为空", advertiserId,startDate,endDate);
+            String errMsg = acquired ? "返回结果为空" : "频控等待超时";
+            log.error("获取快手广告账户流水信息异常:{},accountId:{} {}~{}", errMsg, advertiserId,startDate,endDate);
             if (isLog != null && isLog == 1) {
-                errorLogService.addError(advertiserId, startDate, endDate, "daily_flows", "daily", "返回结果为空", 2);
+                errorLogService.addError(advertiserId, startDate, endDate, "daily_flows", "daily", errMsg, 2);
             }
             return;
         }
@@ -170,10 +181,6 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
         String message = resultJson.getString("message");
         if (null == code || code != 0) {
             if (retry <= 3) {
-                try {
-                    Thread.sleep(800);
-                } catch (InterruptedException ignored) {
-                }
                 queryAccountDailyFlows(accessToken, advertiserId, startDate, endDate, page,isLog, errId, isSend, retry + 1);
             }else {
                 log.error("获取快手广告账户流水信息异常:{},accountId:{} {}~{}", message, advertiserId,startDate,endDate);
@@ -197,9 +204,9 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
                 addList.add(accountReportDaily);
             }
         }
-        //if (!Check.isNull(addList)) {
-        //    accountReportMapper.replaceKuaiShouDailyFlows(addList);
-        //}
+        if (!Check.isNull(addList)) {
+            accountReportMapper.replaceKuaiShouDailyFlows(addList);
+        }
         if (page < totalPage) {
             queryAccountDailyFlows(accessToken, advertiserId, startDate, endDate, page + 1,isLog, errId, isSend, 1);
         } else {
@@ -216,6 +223,53 @@ public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportS
     }
 
     @Override
+    public void queryAccountFund(String accessToken, Long advertiserId, String statDate, Long errId, Integer isSend) {
+        String url = KuaishouLinkConstants.KS_PREFIX + KuaishouLinkConstants.V1_ADVERTISER_FUND_GET;
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", accessToken);
+        Map<String, Object> param = new HashMap<>();
+        param.put("advertiser_id", advertiserId);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
+        if (Check.isNull(result)) {
+            String errMsg = acquired ? "返回结果为空" : "频控等待超时";
+            log.error("获取快手账户余额异常:{},accountId:{}", errMsg, advertiserId);
+            if (errId == null) {
+                errorLogService.addError(advertiserId, statDate, statDate, "fund", "daily", errMsg, 2);
+            }
+            return;
+        }
+        JSONObject resultJson = JSONObject.parseObject(result);
+        Integer code = resultJson.getInteger("code");
+        String message = resultJson.getString("message");
+        if (null == code || code != 0) {
+            log.error("获取快手账户余额异常:{},accountId:{}", message, advertiserId);
+            // 400002 为账户未授权资金scope,属预期情况不记错误
+            if (errId == null && (null == code || code != 400002)) {
+                errorLogService.addError(advertiserId, statDate, statDate, "fund", "daily", message, 2);
+            }
+            return;
+        }
+        JSONObject data = resultJson.getJSONObject("data");
+        if (Check.isNull(data)) {
+            log.error("获取快手账户余额异常:{},accountId:{}", "返回数据为空", advertiserId);
+            if (errId == null) {
+                errorLogService.addError(advertiserId, statDate, statDate, "fund", "daily", "返回数据为空", 2);
+            }
+            return;
+        }
+        KuaishouAdvertiserFund fund = JSONObject.toJavaObject(data, KuaishouAdvertiserFund.class);
+        fund.setAdvertiserId(advertiserId);
+        fund.setStatDate(DateUtils.getIntegerDate(statDate));
+        accountReportMapper.replaceKuaiShouAdvertiserFund(Collections.singletonList(fund));
+        if (errId != null) {
+            errorLogService.deleteInfoByErrorId(errId);
+        }
+        log.info("【{}】录入快手账户余额完成,statDate:{}", advertiserId, statDate);
+    }
+
+    @Override
     public void updateKsAccountStatus() {
         accountReportMapper.updateKsAccountStatus();
     }

+ 152 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/KuaiShouMaterialReportServiceImpl.java

@@ -0,0 +1,152 @@
+package cn.com.ctop.job.kuaishou.data.service.impl;
+
+import cn.com.ctop.job.kuaishou.data.constant.KuaishouLinkConstants;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouMaterialReportDaily;
+import cn.com.ctop.job.kuaishou.data.mapper.KuaiShouMaterialReportMapper;
+import cn.com.ctop.job.kuaishou.data.service.IKuaiShouErrorLogService;
+import cn.com.ctop.job.kuaishou.data.service.IKuaiShouMaterialReportService;
+import cn.com.ctop.job.kuaishou.data.utils.AlertUtils;
+import cn.com.ctop.job.kuaishou.data.utils.Check;
+import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
+import cn.com.ctop.job.kuaishou.data.utils.HttpUtils;
+import cn.com.ctop.job.kuaishou.data.utils.RateLimitUtil;
+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.scheduling.annotation.EnableScheduling;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+@EnableScheduling
+public class KuaiShouMaterialReportServiceImpl implements IKuaiShouMaterialReportService {
+
+    /**
+     * 视频素材报表维度
+     */
+    private static final int VIEW_TYPE_VIDEO = 5;
+
+    /**
+     * 图片素材报表维度
+     */
+    private static final int VIEW_TYPE_IMAGE = 16;
+
+    @Autowired
+    private IKuaiShouErrorLogService errorLogService;
+
+    @Autowired
+    private KuaiShouMaterialReportMapper materialReportMapper;
+
+    @Autowired
+    private RateLimitUtil rateLimitUtil;
+
+    @Override
+    public void queryMaterialReportDaily(String accessToken, Long advertiserId, String startDate, String endDate, int page) {
+        // 视频素材报表(view_type=5)与图片素材报表(view_type=16)各拉一遍
+        queryMaterialReport(accessToken, advertiserId, startDate, endDate, page, VIEW_TYPE_VIDEO, null);
+        queryMaterialReport(accessToken, advertiserId, startDate, endDate, page, VIEW_TYPE_IMAGE, null);
+    }
+
+    @Override
+    public void getMaterialDailyRetry(Long errorId, Long advertiserId, String accessToken, String startDate, String endDate, Integer page, Integer isSend) {
+        int curPage = page == null ? 1 : page;
+        boolean videoOk = queryMaterialReport(accessToken, advertiserId, startDate, endDate, curPage, VIEW_TYPE_VIDEO, errorId);
+        boolean imageOk = queryMaterialReport(accessToken, advertiserId, startDate, endDate, curPage, VIEW_TYPE_IMAGE, errorId);
+        if (videoOk && imageOk && errorId != null) {
+            errorLogService.deleteInfoByErrorId(errorId);
+            if (isSend != null && isSend == 1) {
+                AlertUtils.sendMessage(advertiserId, startDate, endDate, 2, "daily", 1, "material");
+            }
+        }
+    }
+
+    /**
+     * 拉取素材报表并入库
+     *
+     * @param viewType 5-视频素材报表 16-图片素材报表
+     * @param errorId  非空表示重试路径(失败不重复记错误日志)
+     * @return 本次拉取是否成功
+     */
+    private boolean queryMaterialReport(String accessToken, Long advertiserId, String startDate, String endDate, int page, int viewType, Long errorId) {
+        String url = KuaishouLinkConstants.KS_PREFIX + KuaishouLinkConstants.V1_MATERIAL_REPORT;
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", accessToken);
+        Map<String, Object> param = new HashMap<>();
+        if (!Check.isNull(startDate)) {
+            param.put("start_date", startDate);
+        }
+        if (!Check.isNull(endDate)) {
+            param.put("end_date", endDate);
+        }
+        param.put("advertiser_id", advertiserId);
+        param.put("temporal_granularity", "DAILY");
+        param.put("view_type", viewType);
+        param.put("page_size", 2000);
+        param.put("page", page);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
+        if (Check.isNull(result)) {
+            String errMsg = acquired ? "返回结果为空" : "频控等待超时";
+            log.error("获取快手素材日报报表异常:{},accountId:{},viewType:{}", errMsg, advertiserId, viewType);
+            if (errorId == null) {
+                errorLogService.addError(advertiserId, startDate, endDate, "material", "daily", errMsg, 2);
+            }
+            return false;
+        }
+        JSONObject resultJson = JSONObject.parseObject(result);
+        Integer code = resultJson.getInteger("code");
+        String message = resultJson.getString("message");
+        if (null != code && code != 0) {
+            log.error("获取快手素材日报报表异常:{},accountId:{},viewType:{}", message, advertiserId, viewType);
+            if (errorId == null) {
+                errorLogService.addError(advertiserId, startDate, endDate, "material", "daily", message, 2);
+            }
+            return false;
+        }
+        // 素材报表成功响应无code/data包装,details直接位于顶层(实测),同时兼容data包装的返回
+        JSONObject data = resultJson.getJSONObject("data");
+        JSONArray details = null;
+        if (data != null) {
+            details = data.getJSONArray("details");
+        }
+        if (details == null) {
+            details = resultJson.getJSONArray("details");
+        }
+        List<KuaishouMaterialReportDaily> addList = new ArrayList<>();
+        if (!Check.isNull(details)) {
+            for (int i = 0; i < details.size(); i++) {
+                JSONObject detailJson = details.getJSONObject(i);
+                detailJson.put("ad_show", detailJson.getString("show"));
+                detailJson.put("stat_date", Integer.valueOf(DateUtils.getIntegerDate(detailJson.getString("stat_date"))));
+                // 图片素材url为数组,转成JSON字符串入库
+                Object imageUrls = detailJson.get("image_urls");
+                if (imageUrls instanceof JSONArray) {
+                    detailJson.put("image_urls", ((JSONArray) imageUrls).toJSONString());
+                }
+                // aigc_material返回布尔值,转成字符串入库
+                Object aigcMaterial = detailJson.get("aigc_material");
+                if (aigcMaterial instanceof Boolean) {
+                    detailJson.put("aigc_material", String.valueOf(aigcMaterial));
+                }
+                KuaishouMaterialReportDaily materialReportDaily = JSONObject.toJavaObject(detailJson, KuaishouMaterialReportDaily.class);
+                materialReportDaily.setAdvertiserId(advertiserId);
+                addList.add(materialReportDaily);
+            }
+        }
+        if (!Check.isNull(addList)) {
+            materialReportMapper.replaceBatcKuaiShouMaterialReportDaily(addList);
+        }
+        if (!Check.isNull(details) && details.size() >= 2000) {
+            return queryMaterialReport(accessToken, advertiserId, startDate, endDate, page + 1, viewType, errorId);
+        }
+        log.info("【{}】录入快手素材日报数据完成,viewType:{}", advertiserId, viewType);
+        return true;
+    }
+}

+ 15 - 12
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/KuaiShouRetryReportServiceImpl.java

@@ -14,6 +14,7 @@ import cn.com.ctop.job.kuaishou.data.utils.AlertUtils;
 import cn.com.ctop.job.kuaishou.data.utils.Check;
 import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
 import cn.com.ctop.job.kuaishou.data.utils.HttpUtils;
+import cn.com.ctop.job.kuaishou.data.utils.RateLimitUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
@@ -36,6 +37,8 @@ public class KuaiShouRetryReportServiceImpl implements IKuaiShouRetryReportServi
     private IKuaiShouErrorLogService errorLogService;
     @Autowired
     private KuaiShouGroupReportMapper kuaiShouGroupReportMapper;
+    @Autowired
+    private RateLimitUtil rateLimitUtil;
 
     @Override
     public List<JSONObject> getDramaErrorLogs() {
@@ -49,11 +52,6 @@ public class KuaiShouRetryReportServiceImpl implements IKuaiShouRetryReportServi
 
     @Override
     public void getAccountHourRetry(Long errorId, Long advertiserId, String accessToken, String startDate, String endDate, Integer page, Integer isSend) {
-        try {
-            Thread.sleep(1500);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
         String url = "https://ad.e.kuaishou.com/rest/openapi/v1/report/account_report";
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", "application/json");
@@ -69,7 +67,12 @@ public class KuaiShouRetryReportServiceImpl implements IKuaiShouRetryReportServi
         param.put("temporal_granularity", "HOURLY");
         param.put("page_size", 2000);
         param.put("page", page);
-        String result = HttpUtils.httpPostRequest(url, param, headers);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
+        if (Check.isNull(result)) {
+            log.error("获取快手账号时报报表异常:{},accountId:{}", acquired ? "返回结果为空" : "频控等待超时", advertiserId);
+            return;
+        }
         JSONObject resultJson = JSONObject.parseObject(result);
         Integer code = resultJson.getInteger("code");
         String message = resultJson.getString("message");
@@ -107,11 +110,6 @@ public class KuaiShouRetryReportServiceImpl implements IKuaiShouRetryReportServi
 
     @Override
     public void getAccountDailyRetry(Long id, Long advertiserId, String accessToken, String startDate, String endDate, Integer page, Integer isSend) {
-        try {
-            Thread.sleep(1500);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
         String url = "https://ad.e.kuaishou.com/rest/openapi/v1/report/account_report";
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", "application/json");
@@ -127,7 +125,12 @@ public class KuaiShouRetryReportServiceImpl implements IKuaiShouRetryReportServi
         param.put("temporal_granularity", "DAILY");
         param.put("page_size", 2000);
         param.put("page", page);
-        String result = HttpUtils.httpPostRequest(url, param, headers);
+        boolean acquired = rateLimitUtil.acquire(url);
+        String result = acquired ? HttpUtils.httpPostRequest(url, param, headers) : null;
+        if (Check.isNull(result)) {
+            log.error("获取快手账号日报报表异常:{},accountId:{}", acquired ? "返回结果为空" : "频控等待超时", advertiserId);
+            return;
+        }
         JSONObject resultJson = JSONObject.parseObject(result);
         Integer code = resultJson.getInteger("code");
         String message = resultJson.getString("message");

+ 88 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/utils/RateLimitUtil.java

@@ -0,0 +1,88 @@
+package cn.com.ctop.job.kuaishou.data.utils;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RRateLimiter;
+import org.redisson.api.RateIntervalUnit;
+import org.redisson.api.RateType;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 快手 OpenAPI 频频控制工具(基于 Redisson RRateLimiter 的分布式频控)
+ * <p>
+ * 快手接口限流为全局维度(实测不同 token 也会相互触发 400001 限流),
+ * 因此频控 key 不区分账户,全实例共享同一速率,多线程/多任务调用时
+ * 在 Redis 层统一排队。
+ * 限流参数(interval 内许可数, 间隔毫秒)按下表配置,可直接调整:
+ * <ul>
+ *     <li>material_report:1 次 / 10 秒 —— 实测连续调用 2~3 次即触发限流,恢复需 30 秒以上</li>
+ *     <li>account_report:1 次 / 1.5 秒 —— 与原 Thread.sleep(1500) 节奏一致</li>
+ *     <li>其余接口默认:1 次 / 1.5 秒</li>
+ * </ul>
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class RateLimitUtil {
+    @Autowired
+    public RedissonClient redissonClient;
+
+    private static final Map<String, Boolean> initMap = new ConcurrentHashMap<>();
+
+    /**
+     * 快手接口频控配置:path -> {interval 内许可数, 间隔毫秒}
+     */
+    private static final Map<String, int[]> pathLimitMap = new HashMap<>();
+
+    static {
+        pathLimitMap.put("/rest/openapi/v1/report/material_report", new int[]{2, 10000});
+        pathLimitMap.put("/rest/openapi/v1/report/account_report", new int[]{2, 1500});
+        pathLimitMap.put("/rest/openapi/v1/advertiser/fund/get", new int[]{2, 1500});
+        pathLimitMap.put("/rest/openapi/v1/advertiser/fund/daily_flows", new int[]{2, 1500});
+    }
+
+    /**
+     * 获取调用许可(最多等待 30 秒),false 表示仍未排到需放弃本次调用
+     */
+    public boolean acquire(String url) {
+        return acquire(url, 30);
+    }
+
+    /**
+     * 获取调用许可
+     *
+     * @param timeoutSeconds 最多等待秒数
+     */
+    public boolean acquire(String url, int timeoutSeconds) {
+        URI uri = URI.create(url);
+        String path = uri.getPath();
+        String limitKey = path.replaceAll("/$", "").replace("/", ":");
+        String key = "rate:limit:ks" + limitKey;
+        try {
+            if (!initMap.containsKey(key)) {
+                int[] limit = pathLimitMap.getOrDefault(path, new int[]{1, 1500});
+                RRateLimiter limiter = redissonClient.getRateLimiter(key);
+                limiter.setRate(
+                        RateType.OVERALL,
+                        limit[0],
+                        limit[1],
+                        RateIntervalUnit.MILLISECONDS
+                );
+                initMap.put(key, true);
+            }
+            return redissonClient.getRateLimiter(key).tryAcquire(1, timeoutSeconds, TimeUnit.SECONDS);
+        } catch (Exception e) {
+            // Redis 异常时降级放行,避免频控组件故障阻断全部报表任务
+            log.error("频控获取许可异常,降级放行,url:{}", url, e);
+            return true;
+        }
+    }
+}

+ 20 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouAccountReportJob.java

@@ -167,5 +167,25 @@ public class KuaiShouAccountReportJob {
         });
     }
 
+    @XxlJob("queryNowDateAccountFundJob")
+    public void queryNowDateAccountFundJob() {
+        String param = XxlJobHelper.getJobParam(); // 执行参数
+        if (Check.isNull(param)) {
+            log.error("入参为空");
+            return;
+        }
+        String[] s = param.split("_");
+        Long advertiserId = Long.valueOf(s[0]);
+        String accessToken = s[1];
+
+        String nowDate = DateUtil.formatDate(new Date());
+
+        yesAccountExecutorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                accountReportService.queryAccountFund(accessToken, advertiserId, nowDate, null, 2);
+            }
+        });
+    }
 
 }

+ 69 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouMaterialReportJob.java

@@ -0,0 +1,69 @@
+package cn.com.ctop.job.kuaishou.handler;
+
+
+import cn.com.ctop.job.kuaishou.data.service.IKuaiShouMaterialReportService;
+import cn.com.ctop.job.kuaishou.data.utils.Check;
+import cn.com.ctop.job.kuaishou.data.utils.DateUtils;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.util.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+@Slf4j
+@Component
+public class KuaiShouMaterialReportJob {
+    @Autowired
+    private IKuaiShouMaterialReportService materialReportService;
+    static ExecutorService nowMaterialexecutorService = Executors.newFixedThreadPool(5);
+    static ExecutorService yesMaterialexecutorService = Executors.newFixedThreadPool(5);
+
+
+    @XxlJob("queryYesDateMaterialReportDailyJob")
+    public void queryYesDateMaterialReportDailyJob() {
+        String param = XxlJobHelper.getJobParam(); // 执行参数
+        if (Check.isNull(param)) {
+            log.error("入参为空");
+            return;
+        }
+        String[] s = param.split("_");
+        Long advertiserId = Long.valueOf(s[0]);
+        String accessToken = s[1];
+
+        String nowDate = DateUtil.formatDate(new Date());
+        String yesDate = DateUtils.getAnotherDay("yyyy-MM-dd", nowDate, -1);
+
+        yesMaterialexecutorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                materialReportService.queryMaterialReportDaily(accessToken, advertiserId, yesDate, yesDate, 1);
+            }
+        });
+    }
+
+
+    @XxlJob("queryNowDateMaterialReportDailyJob")
+    public void queryNowDateMaterialReportDailyJob() {
+        String param = XxlJobHelper.getJobParam(); // 执行参数
+        if (Check.isNull(param)) {
+            log.error("入参为空");
+            return;
+        }
+        String[] s = param.split("_");
+        Long advertiserId = Long.valueOf(s[0]);
+        String accessToken = s[1];
+        String nowDate = DateUtil.formatDate(new Date());
+        nowMaterialexecutorService.submit(new Runnable() {
+            @Override
+            public void run() {
+                materialReportService.queryMaterialReportDaily(accessToken, advertiserId, nowDate, nowDate, 1);
+            }
+        });
+    }
+}

+ 23 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouRetryReportJob.java

@@ -45,6 +45,9 @@ public class KuaiShouRetryReportJob {
     @Autowired
     private IKuaiShouGroupReportService groupReportService;
 
+    @Autowired
+    private IKuaiShouMaterialReportService materialReportService;
+
     @XxlJob("kuaiShouRetryReport")
     public void promoterReport() throws Exception {
         List<JSONObject> accountList = retryReportService.getErrorLogs();
@@ -114,6 +117,15 @@ public class KuaiShouRetryReportJob {
                             }
                         }
                     });
+                } else if ("fund".equals(dataDimension)) {
+                    adSocialExecutorService.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (!Check.isNull(accessToken)) {
+                                accountReportService.queryAccountFund(accessToken, advertiserId, startDate, id, isSend);
+                            }
+                        }
+                    });
                 } else if ("group_list".equals(dataDimension)) {
                     dailyAccountExecutorService.submit(new Runnable() {
                         @Override
@@ -123,6 +135,17 @@ public class KuaiShouRetryReportJob {
                             }
                         }
                     });
+                } else if ("material".equals(dataDimension)) {
+                    if (dataType.equals("daily")) { // 素材日报
+                        dailyAccountExecutorService.submit(new Runnable() {
+                            @Override
+                            public void run() {
+                                if (!Check.isNull(accessToken)) {
+                                    materialReportService.getMaterialDailyRetry(id, advertiserId, accessToken, startDate, endDate, 1, isSend);
+                                }
+                            }
+                        });
+                    }
                 }
             }
         } else {

+ 1 - 1
job-kuaishou/src/main/resources/application.yml

@@ -1,5 +1,5 @@
 server:
-  port: 8086
+  port: 8087
   shutdown: graceful   #IMMEDIATE立即停机(默认值)、GRACEFUL
   ip: 127.0.0.1
   servlet: