Jelajahi Sumber

头条时段消耗预警 转内网

zhaoxian 11 bulan lalu
induk
melakukan
d464633704
15 mengubah file dengan 1133 tambahan dan 14 penghapusan
  1. 27 2
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/BytedanceController.java
  2. 153 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/Project.java
  3. 172 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/UserAllocation.java
  4. 18 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/BytedanceAdvertiserHourlyReportMapper.java
  5. 72 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/UserAllocationMapper.java
  6. 20 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/BytedanceAdvertiserHourlyReportMapper.xml
  7. 8 10
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/OauthTokenMapper.xml
  8. 268 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/UserAllocationMapper.xml
  9. 6 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IByteDanceHourlyAccountWarningService.java
  10. 65 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IUserAllocationService.java
  11. 119 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/ByteDanceHourlyAccountWarningServiceImpl.java
  12. 2 2
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/BytedanceProjectServiceImpl.java
  13. 150 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/impl/UserAllocationServiceImpl.java
  14. 4 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/utils/DateUtils.java
  15. 49 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceHourlyAccountWarningLoadJob.java

+ 27 - 2
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/BytedanceController.java

@@ -2,7 +2,17 @@ package cn.com.ctop.job.bytedance.controller;
 
 
 import cn.com.ctop.job.bytedance.data.constant.CtopAdConstant;
 import cn.com.ctop.job.bytedance.data.constant.CtopAdConstant;
 import cn.com.ctop.job.bytedance.data.entity.OauthToken;
 import cn.com.ctop.job.bytedance.data.entity.OauthToken;
-import cn.com.ctop.job.bytedance.data.service.*;
+import cn.com.ctop.job.bytedance.data.service.IByteDanceAdvertiserDataService;
+import cn.com.ctop.job.bytedance.data.service.IByteDanceHourlyAccountWarningService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceCampaignReportDailyService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceCampaignReportHourlyService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceCreativeReportDailyService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceCreativeReportHourlyService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceFileVideoGetService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceFundService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceMaterialReportDailyService;
+import cn.com.ctop.job.bytedance.data.service.IBytedanceProjectService;
+import cn.com.ctop.job.bytedance.data.service.IOauthTokenService;
 import cn.com.ctop.job.bytedance.data.utils.Check;
 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.DateUtils;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
@@ -67,6 +77,21 @@ public class BytedanceController {
         listService.checkAdvertiserProject(oauthToken, nowDate, 1);
         listService.checkAdvertiserProject(oauthToken, nowDate, 1);
     }
     }
 
 
+    @Autowired
+    private IByteDanceHourlyAccountWarningService byteDanceHourlyAccountWarningService;
+    static ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    @GetMapping(value = "/testD")
+    public void testD() {
+        List<Long> tokens = tokenService.getAllToutiaoAccountIds();
+        String nowDateStr = DateUtils.getNowDate("yyyy-MM-dd");
+        Integer nowDateInt = DateUtils.getIntegerDate(nowDateStr);
+        Integer yesterdaInt = DateUtils.getIntegerDate(DateUtils.getAnotherDay("yyyy-MM-dd", nowDateStr, -1));
+        tokens.forEach(accountId -> byteDanceHourlyAccountWarningService.byteDanceAccountWarning(accountId, nowDateInt, yesterdaInt));
+
+
+    }
+
 
 
     private static ExecutorService dailyExecutorService = Executors.newFixedThreadPool(10);
     private static ExecutorService dailyExecutorService = Executors.newFixedThreadPool(10);
     @Autowired
     @Autowired
@@ -237,7 +262,7 @@ public class BytedanceController {
 
 
         }
         }
 
 
-        }
+    }
 
 
 
 
 }
 }

+ 153 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/Project.java

@@ -0,0 +1,153 @@
+package cn.com.ctop.job.bytedance.data.entity;
+
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 项目
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-11-19
+ */
+@Data
+@TableName("ctop_project")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_project对象", description = "项目")
+public class Project {
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 项目名称
+     */
+    @Excel(name = "项目名称", width = 15)
+    @ApiModelProperty(value = "项目名称")
+    private String projectName;
+    /**
+     * 广告主id
+     */
+    @Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private String advertiserId;
+
+
+    @Excel(name = "产品id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private Long productId;
+
+    /**
+     * 创建人
+     */
+    @Excel(name = "创建人", width = 15)
+    @ApiModelProperty(value = "创建人")
+    private String userId;
+    /**
+     * 负责人id
+     */
+    @Excel(name = "负责人id", width = 15)
+    @ApiModelProperty(value = "负责人id")
+    private String responsibleId;
+
+
+    @Excel(name = "设计负责人", width = 15)
+    @ApiModelProperty(value = "设计负责人")
+    private String designResponsibleId;
+
+
+    @Excel(name = "公司id", width = 15)
+    @ApiModelProperty(value = "公司id")
+    private String companyId;
+    /**
+     * 媒体类型
+     */
+    @Excel(name = "媒体类型", width = 15)
+    @ApiModelProperty(value = "媒体类型")
+    private String mediaId;
+
+    /**
+     * 最高出价
+     */
+    private Long maxBid;
+
+    private String supplierCode;
+
+
+    // 销售
+    private String saleId;
+    /**
+     * 最高深度转化出价
+     */
+    private BigDecimal maxDeepCpaBid;
+    private Integer checkLink;
+    private Integer materialShare;
+    /**
+     * 创建时间
+     */
+    @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+
+
+    //优化目标出价类型
+    private String bidType;
+
+    //转化目标
+    private String ocpxActionType;
+
+    //深度转化目标
+    private String deepConversionType;
+
+    @TableField(exist = false)
+    private String responsibleId_dictText; // 运营负责人
+
+    @TableField(exist = false)
+    private String saleId_dictText; // 销售
+
+    @TableField(exist = false)
+    private String designResponsibleId_dictText; // 设计负责人
+    @TableField(exist = false)
+    private String advertiserId_dictText; // 广告主名称
+    @TableField(exist = false)
+    private String productId_dictText; // 产品名称
+    @TableField(exist = false)
+    private Integer needExamine;
+    @TableField(exist = false)
+    private String supplierCode_dictText;
+
+    //转化目标
+    @TableField(exist = false)
+    private JSONArray ocpxActionTypeArray;
+
+    //深度转化目标
+    @TableField(exist = false)
+    private JSONArray deepConversionTypeArray;
+}

+ 172 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/entity/UserAllocation.java

@@ -0,0 +1,172 @@
+package cn.com.ctop.job.bytedance.data.entity;
+
+import cn.com.ctop.job.bytedance.data.annotation.Dict;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 用户分配
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-08-08
+ */
+@Data
+@TableName("ctop_user_allocation")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_user_allocation对象", description = "用户分配")
+public class UserAllocation {
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+    /**
+     * 登陆人id
+     */
+    @Excel(name = "登陆人id", width = 15)
+    @ApiModelProperty(value = "登陆人id")
+    private String userId;
+
+
+    @Excel(name = "登陆人名称", width = 15)
+    @ApiModelProperty(value = "登陆人名称")
+    private String userName;
+
+    /**
+     * 账户id --授权
+     */
+    @Excel(name = "账户id --授权", width = 15)
+    @ApiModelProperty(value = "账户id --授权")
+    private Long accountId;
+    /**
+     * 广告主ID
+     */
+    @Excel(name = "广告主ID", width = 15)
+    @ApiModelProperty(value = "广告主ID")
+    private String advertiserId;
+
+    private String systemType;
+
+    /**
+     * 项目id
+     */
+    @Dict(dicCode = "id", dictTable = "ctop_project", dicText = "project_name")
+    private Long projectId;
+
+    /**
+     * 输入账号  --登陆
+     */
+    @Excel(name = "输入账号  --登陆", width = 15)
+    @ApiModelProperty(value = "输入账号  --登陆")
+    private String accountName;
+
+    /**
+     * 预警 金额
+     */
+    private BigDecimal warningAmount;
+
+    /**
+     * 预警 比例
+     */
+    private BigDecimal warningProportion;
+
+    /**
+     * 创建时间
+     */
+    @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    /**
+     * 授权名称
+     */
+    @Excel(name = "授权名称", width = 15)
+    @ApiModelProperty(value = "授权名称")
+    private String authName;
+
+    /**
+     * 授权开始时间
+     */
+    @Excel(name = "授权开始时间", width = 15)
+    @ApiModelProperty(value = "授权开始时间")
+    private String authBeginTime;
+
+
+    /**
+     * 0 启动
+     * 1 禁用
+     */
+    private Integer accountStatus;
+
+    /**
+     * 检测链接预警
+     * 0 启动
+     * 1 禁用
+     */
+    private Integer monitoringLink;
+
+    /**
+     * 检测链接预警
+     * 0 启动
+     * 1 禁用
+     */
+    private Integer landingPage;
+
+    /**
+     * 是否开启删评论
+     * 0 启动
+     * 1 禁用
+     */
+    private Integer deleteComment;
+    /**
+     * 自动投放,0关闭,1开启
+     */
+    private Integer autoDelivery;
+    /**
+     * 物料类型 0-不同步,1应用包,(2人群包,3定向包)
+     */
+    private String materialType;
+
+    /**
+     * 修改时间
+     */
+    @Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+    /**
+     * 平台类型 1 头条 2快手
+     */
+    @Excel(name = "平台类型 1 头条 2快手", width = 15)
+    @ApiModelProperty(value = "平台类型 1 头条 2快手")
+    private String mediaId;
+
+
+
+
+   /* @TableField(exist = false)
+    private String advertiserName;
+
+    @TableField(exist = false)
+    private String projectName;*/
+
+}

+ 18 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/BytedanceAdvertiserHourlyReportMapper.java

@@ -0,0 +1,18 @@
+package cn.com.ctop.job.bytedance.data.mapper;
+
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+
+/**
+ * @Description: 广告主小时级别报表信息
+ * @Author: jeecg-boot
+ * @Date: 2019-09-10
+ * @Version: V1.0
+ */
+public interface BytedanceAdvertiserHourlyReportMapper {
+
+    Integer selectMaxHour(@Param("accountId") Long accountId, @Param("statDate") Integer statDate);
+
+    BigDecimal getCost(@Param("accountId") Long accountId, @Param("statHour") Integer statHour, @Param("statDate") Integer statDate);
+}

+ 72 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/UserAllocationMapper.java

@@ -0,0 +1,72 @@
+package cn.com.ctop.job.bytedance.data.mapper;
+
+import cn.com.ctop.job.bytedance.data.entity.Project;
+import cn.com.ctop.job.bytedance.data.entity.UserAllocation;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Description: 用户分配
+ * @Author: jeecg-boot
+ * @Date: 2019-08-08
+ * @Version: V1.0
+ */
+public interface UserAllocationMapper extends BaseMapper<UserAllocation> {
+    List<UserAllocation> selectAccountListByProjectId(@Param("projectId") Long projectId);
+
+    String queryAdvertiserId(@Param("accountId") Long accountId);
+
+    String queryUserIdByAccountId(@Param("accountId") Long accountId);
+
+    List<JSONObject> getAccountListByProject(@Param("projectId") Long projectId);
+
+    List<JSONObject> getUserIdListByProjectId(@Param("projectId") Long projectId);
+
+    List<JSONObject> getAccountIdListByUserId(@Param("userId") String userId);
+
+    List<JSONObject> getAccountIdsByUserId(@Param("userId") String userId);
+
+    List<JSONObject> getAllAccountIdsByMediaId(@Param("mediaId") String mediaId);
+
+    Long getProjectIdByAccountId(@Param("accountId") Long accountId);
+
+    UserAllocation getUserAllocation(@Param("accountId") Long accountId);
+
+    JSONObject getSwitchStatusByAccount(@Param("accountId") Long accountId);
+
+    List<Long> queryAccountsByDeleteComment();
+
+    String getCompanyNameByUserId(@Param("planId") String planId);
+
+    List<UserAllocation> listByMediaId(@Param("mediaId") String mediaId, @Param("accountStatus") Integer accountStatus);
+
+    List<JSONObject> getAccountListByProjectList(@Param("list") List list);
+
+    List<Long> getValidProjectIds(@Param("mediaId") Integer mediaId);
+
+    List<UserAllocation> getAccountListByUserIdAndProductId(@Param("userId") String userId, @Param("projectId") Long projectId, @Param("productId") Long productId);
+
+    List<JSONObject> getUserIdListByProductId(@Param("productId") Long productId);
+
+    List<JSONObject> getByAccountIds(@Param("accountIds") JSONArray accountIds);
+
+    List<Long> getKuaiShouUserIdListByProjectId(@Param("projectId") Long projectId);
+
+    List<JSONObject> selectAccountsByKuaishouUserId(@Param("userId") Long userId);
+
+    int updateProjectStrategyStatus(@Param("accountId") Long accountId, @Param("projectStrategy") Integer projectStrategy);
+
+    List<Long> queryAutomaticAccounts(@Param("projectId") Long projectId);
+
+    List<Long> getIdList();
+
+    JSONObject getProjectByAccountId(Long accountId);
+
+    Project getProjectEntity(Long projectId);
+
+    UserAllocation getOneByAccountId();
+}

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

@@ -0,0 +1,20 @@
+<?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.BytedanceAdvertiserHourlyReportMapper">
+
+    <select id="selectMaxHour" resultType="java.lang.Integer">
+        select max(`hour`)
+        from application.bytedance_advertiser_report_hourly_dw
+        where account_id = #{accountId}
+          and stat_datetime = #{statDate}
+    </select>
+
+    <select id="getCost" resultType="java.math.BigDecimal">
+        select cost
+        from application.bytedance_advertiser_report_hourly_dw
+        where account_id = #{accountId}
+          and stat_datetime = #{statDate}
+          and `hour` = #{statHour}
+    </select>
+
+</mapper>

+ 8 - 10
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/mapper/xml/OauthTokenMapper.xml

@@ -17,10 +17,13 @@
     </select>
     </select>
 
 
     <select id="getAllToutiaoAccountIds" resultType="Long">
     <select id="getAllToutiaoAccountIds" resultType="Long">
-        SELECT account_id
-        FROM `jeecg-boot`.ctop_user_allocation
-        WHERE media_id = 1
-          and account_status = 0
+        SELECT t1.account_id
+        FROM `jeecg-boot`.ctop_oauth_token t1
+                 LEFT JOIN `jeecg-boot`.ctop_user_allocation t2
+                           ON t1.account_id = t2.account_id
+        WHERE t1.media_id IN (1, 3)
+          AND t2.account_status = 0
+        GROUP BY t1.account_id
     </select>
     </select>
 
 
     <select id="getAgentToken" resultType="java.lang.String">
     <select id="getAgentToken" resultType="java.lang.String">
@@ -52,12 +55,7 @@
     </select>
     </select>
 
 
     <select id="getProjectByAccountId" resultType="com.alibaba.fastjson.JSONObject">
     <select id="getProjectByAccountId" resultType="com.alibaba.fastjson.JSONObject">
-        select id                   'projectId',
-               project_name         'projectName',
-               max_bid              'maxBid',
-               bid_type             'bidType',
-               ocpx_action_type     'ocpxActionType',
-               deep_conversion_type 'deepConversionType'
+        select id 'projectId', project_name 'projectName', max_bid 'maxBid', bid_type 'bidType', ocpx_action_type 'ocpxActionType', deep_conversion_type 'deepConversionType'
         from `jeecg-boot`.ctop_project
         from `jeecg-boot`.ctop_project
         where id = (
         where id = (
             select project_id
             select project_id

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

@@ -0,0 +1,268 @@
+<?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.UserAllocationMapper">
+
+    <select id="selectAccountListByProjectId" resultType="cn.com.ctop.job.bytedance.data.entity.UserAllocation">
+        select a.user_id    as userId,
+               a.user_name  as userName,
+               a.auth_name  as authName,
+               a.account_id as accountId
+        from `jeecg-boot`.ctop_user_allocation a
+                 left join `jeecg-boot`.ctop_project b on a.project_id = b.id
+        where b.id = #{projectId}
+          and account_status = 0
+    </select>
+    <select id="getAccountListByUserIdAndProductId" resultType="cn.com.ctop.job.bytedance.data.entity.UserAllocation">
+        select cua.account_id, cua.auth_name, cua.user_name
+        from `jeecg-boot`.ctop_user_allocation cua
+        left join `jeecg-boot`.ctop_project cp on cua.project_id = cp.id
+        where
+        cua.project_id = #{projectId}
+        and
+        cp.product_id=#{productId}
+        <if test="userId != null and userId != ''">
+            and cua.user_id = #{userId}
+        </if>
+
+    </select>
+
+    <select id="getOneByAccountId" resultType="cn.com.ctop.job.bytedance.data.entity.UserAllocation">
+        select id,
+               user_id,
+               user_name,
+               account_id,
+               advertiser_id,
+               advertiser_name,
+               project_id,
+               project_name,
+               account_name,
+               warning_amount,
+               warning_proportion,
+               account_status,
+               auth_name,
+               system_type,
+               monitoring_link,
+               landing_page,
+               delete_comment,
+               project_strategy,
+               auto_delivery,
+               material_type,
+               media_id,
+               create_time,
+               update_time,
+               delivery_point,
+               auth_begin_time,
+               manager,
+               project_media_id
+        from `jeecg-boot`.ctop_user_allocation
+        where account_id = #{accountId}
+    </select>
+
+    <select id="queryAdvertiserId" resultType="String">
+        select distinct advertiser_id
+        from `jeecg-boot`.ctop_user_allocation
+        where account_id = #{accountId}
+    </select>
+    <select id="queryUserIdByAccountId" resultType="String">
+        select distinct user_id
+        from `jeecg-boot`.ctop_user_allocation
+        where account_id = #{accountId}
+    </select>
+
+    <select id="getAccountListByProject" resultType="com.alibaba.fastjson.JSONObject">
+        select t1.account_id as 'accountId', (select realname from `jeecg-boot`.sys_user where id = t1.user_id) as 'userName', t1.auth_name as 'authName'
+        from `jeecg-boot`.ctop_user_allocation t1
+        where t1.project_id = #{projectId}
+        order by t1.create_time desc
+    </select>
+
+    <select id="getAccountListByProjectList" resultType="com.alibaba.fastjson.JSONObject">
+        select
+        t1.project_id as 'projectId',
+        t1.account_id as 'accountId',
+        (select realname from `jeecg-boot`.sys_user where id = t1.user_id ) as 'userName',
+        t1.auth_name as 'authName',
+        t1.account_status as 'accountStatus'
+        from `jeecg-boot`.ctop_user_allocation t1
+        where t1.project_id in
+        <foreach collection="list" item="item" separator=","
+                 open="(" close=")">
+            #{item}
+        </foreach>
+        order by t1.create_time desc
+    </select>
+
+
+    <select id="getUserIdListByProjectId" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT t1.user_id as 'userId', t1.account_id as 'accountId', t1.user_name as 'userName'
+        from `jeecg-boot`.ctop_kuaishou_advertiser_base_info t1
+                 LEFT JOIN
+             `jeecg-boot`.ctop_user_allocation t2
+             ON t1.account_id = t2.account_id
+        WHERE t2.project_id = #{projectId}
+          AND t2.account_status = 0
+        GROUP BY t1.user_id;
+    </select>
+    <select id="getUserIdListByProductId" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT t1.user_id as 'userId', t1.account_id as 'accountId', t1.user_name as 'userName'
+        from `jeecg-boot`.ctop_kuaishou_advertiser_base_info t1
+                 LEFT JOIN `jeecg-boot`.ctop_user_allocation t2
+                           ON t1.account_id = t2.account_id
+                 LEFT JOIN `jeecg-boot`.ctop_project t3
+                           ON t2.project_id = t3.id
+        WHERE t3.product_id = #{productId}
+          AND t2.account_status = 0
+        GROUP BY t1.user_id;
+    </select>
+
+    <select id="getValidProjectIds" resultType="java.lang.Long">
+        SELECT project_id FROM `jeecg-boot`.ctop_user_allocation t1
+        where account_status = 0
+        <if test="mediaId != null">
+            AND media_id = #{mediaId}
+        </if>
+        GROUP BY project_id
+    </select>
+
+
+    <select id="getAccountIdListByUserId" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT t1.account_id as 'accountId', t1.auth_name as 'authName', t1.user_name as 'userName'
+        from `jeecg-boot`.ctop_user_allocation t1
+                 LEFT JOIN `jeecg-boot`.ctop_kuaishou_advertiser_base_info t2
+                           ON t1.account_id = t2.account_id
+        WHERE t2.user_id = #{userId}
+          AND t1.account_status = 0
+    </select>
+
+    <select id="getAccountIdsByUserId" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT allocation.account_id,
+               allocation.auth_name,
+               project.project_name as project_name
+        FROM `jeecg-boot`.ctop_user_allocation allocation
+                 left join `jeecg-boot`.ctop_project project on allocation.project_id = project.id
+        WHERE allocation.user_id = #{userId}
+          and allocation.account_status = 0
+    </select>
+
+
+    <select id="getAllAccountIdsByMediaId" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT account_id,
+               auth_name,
+               project_name
+        FROM `jeecg-boot`.ctop_user_allocation
+        WHERE media_id = #{mediaId}
+          and account_status = 0
+    </select>
+
+    <select id="getProjectIdByAccountId" resultType="java.lang.Long">
+        select project_id
+        from `jeecg-boot`.ctop_user_allocation
+        where account_id = #{accountId} limit 1
+    </select>
+
+    <select id="getUserAllocation" resultType="cn.com.ctop.job.bytedance.data.entity.UserAllocation">
+        select *
+        from `jeecg-boot`.ctop_user_allocation
+        where account_id = #{accountId} limit 1
+    </select>
+
+    <select id="getSwitchStatusByAccount" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT monitoring_link,
+               landing_page
+        FROM `jeecg-boot`.ctop_user_allocation
+        WHERE account_id = #{accountId}
+    </select>
+
+    <select id="queryAccountsByDeleteComment" resultType="java.lang.Long">
+        SELECT account_id
+        FROM `jeecg-boot`.ctop_user_allocation
+        WHERE media_id = 2
+          AND account_status = 0
+          AND delete_comment = 0
+    </select>
+    <select id="getCompanyNameByUserId" resultType="java.lang.String">
+        select company_name
+        from `jeecg-boot`.user_company
+        where user_id = #{planId} limit 1
+    </select>
+    <select id="listByMediaId" resultType="cn.com.ctop.job.bytedance.data.entity.UserAllocation">
+        select a.* from `jeecg-boot`.ctop_user_allocation a
+        left join `jeecg-boot`.ctop_project p on p.id = a.project_id
+        where
+        1=1
+        <if test="null!=accountStatus">
+            and a.account_status = #{accountStatus}
+        </if>
+        <if test="null!=mediaId">
+            and p.media_id = #{mediaId}
+        </if>
+    </select>
+    <select id="getByAccountIds" resultType="com.alibaba.fastjson.JSONObject">
+        select
+        account_id as 'accountId',
+        auth_name as 'authName'
+        from `jeecg-boot`.ctop_user_allocation where
+        account_id in
+        <foreach collection="accountIds" item="item" separator=","
+                 open="(" close=")">
+            #{item}
+        </foreach>
+
+
+    </select>
+    <select id="getKuaiShouUserIdListByProjectId" resultType="java.lang.Long">
+        select t2.user_id
+        from `jeecg-boot`.ctop_user_allocation t1
+                 left join `jeecg-boot`.ctop_kuaishou_advertiser_base_info t2
+                           on t1.account_id = t2.account_id
+        where t1.project_id = #{projectId}
+        group by t2.user_id
+    </select>
+    <select id="selectAccountsByKuaishouUserId" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT t2.account_id AS 'accountId', t2.user_name AS 'userName', t2.auth_name AS 'authName', t2.account_status AS 'accountStatus'
+        FROM `jeecg-boot`.ctop_kuaishou_advertiser_base_info t1
+                 LEFT JOIN `jeecg-boot`.ctop_user_allocation t2 ON t1.account_id = t2.account_id
+        WHERE t1.user_id = #{userId}
+          AND t2.id IS NOT NULL;
+
+    </select>
+
+    <update id="updateProjectStrategyStatus">
+        update `jeecg-boot`.ctop_user_allocation
+        set auto_delivery = #{projectStrategy}
+        where account_id = #{accountId}
+    </update>
+
+    <select id="queryAutomaticAccounts" resultType="java.lang.Long">
+        select account_id
+        from `jeecg-boot`.ctop_user_allocation
+        where project_id = #{projectId}
+          AND auto_delivery = 1
+    </select>
+    <select id="getIdList" resultType="java.lang.Long">
+        SELECT account_id
+        FROM `jeecg-boot`.ctop_track_monitor_configure
+        where status = 0
+
+    </select>
+
+
+    <select id="getProjectByAccountId" resultType="com.alibaba.fastjson.JSONObject">
+        select id 'projectId', project_name 'projectName', max_bid 'maxBid', bid_type 'bidType', ocpx_action_type 'ocpxActionType', deep_conversion_type 'deepConversionType'
+        from `jeecg-boot`.ctop_project
+        where id = (
+            select project_id
+            from `jeecg-boot`.ctop_user_allocation
+            where account_id = #{accountId}
+            limit 1
+            )
+    </select>
+
+    <select id="getProjectEntity" resultType="cn.com.ctop.job.bytedance.data.entity.Project">
+        select *
+        from `jeecg-boot`.ctop_project
+        where id = #{projectId}
+    </select>
+
+
+</mapper>

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

@@ -0,0 +1,6 @@
+package cn.com.ctop.job.bytedance.data.service;
+
+public interface IByteDanceHourlyAccountWarningService {
+
+    void byteDanceAccountWarning(Long account, Integer nowDate, Integer yesterda);
+}

+ 65 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/data/service/IUserAllocationService.java

@@ -0,0 +1,65 @@
+package cn.com.ctop.job.bytedance.data.service;
+
+import cn.com.ctop.job.bytedance.data.entity.Project;
+import cn.com.ctop.job.bytedance.data.entity.UserAllocation;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 用户分配
+ * @Author: jeecg-boot
+ * @Date: 2019-08-08
+ * @Version: V1.0
+ */
+public interface IUserAllocationService extends IService<UserAllocation> {
+
+    UserAllocation getByAccountId(Long accountId);
+
+    List<UserAllocation> listByMediaId(String mediaId, int accountStatus);
+
+    String getAdvertiserIdByAccountId(Long accountId);
+
+    List<JSONObject> getAccountListByProject(Long projectId);
+
+    List<JSONObject> getUserIdListByProjectId(Long projectId);
+
+    List<JSONObject> getAccountIdListByUserId(String userId);
+
+    JSONObject getSwitchStatusByAccount(Long accountId);
+
+    List<Long> getAccountsByDeleteComment();
+
+    List<UserAllocation> getAccountListByUserIdAndProductId(String userId, Long projectId, Long productId);
+
+    Map<Long, List<JSONObject>> getAccountListByProjectList(List<JSONObject> projectList);
+
+    List<JSONObject> getUserIdListByProductId(Long productId);
+
+    /**
+     * 获取有效的项目ID集合
+     *
+     * @param mediaId 平台类型 1 头条 2快手
+     * @throws
+     */
+    List<Long> getValidProjectIds(Integer mediaId);
+
+    List<JSONObject> getByAccountIds(JSONArray accountIds);
+
+    List<Long> getKuaiShouUserIdListByProjectId(Long projectId);
+
+    List<JSONObject> selectAccountsByKuaishouUserId(Long userId);
+
+    boolean updateProjectStrategyStatus(Long accountId, Integer projectStrategy);
+
+    List<Long> queryAutomaticAccounts(Long projectId);
+
+    List<Long> getIdList();
+
+    JSONObject getProjectByAccountId(Long accountId);
+
+    Project getProjectEntity(Long projectId);
+}

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

@@ -0,0 +1,119 @@
+package cn.com.ctop.job.bytedance.data.service.impl;
+
+import cn.com.ctop.job.bytedance.data.entity.Project;
+import cn.com.ctop.job.bytedance.data.entity.UserAllocation;
+import cn.com.ctop.job.bytedance.data.mapper.BytedanceAdvertiserHourlyReportMapper;
+import cn.com.ctop.job.bytedance.data.mapper.BytedanceProjectMapper;
+import cn.com.ctop.job.bytedance.data.service.IByteDanceHourlyAccountWarningService;
+import cn.com.ctop.job.bytedance.data.service.IUserAllocationService;
+import cn.com.ctop.job.bytedance.data.utils.Check;
+import cn.com.ctop.job.bytedance.data.utils.weixin.CorpWexinUtils;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+@Service
+@Primary
+@Slf4j
+public class ByteDanceHourlyAccountWarningServiceImpl implements IByteDanceHourlyAccountWarningService {
+
+    @Autowired
+    private BytedanceAdvertiserHourlyReportMapper bytedanceAdvertiserHourlyReportMapper;
+    @Autowired
+    private IUserAllocationService userAllocationService;
+
+    @Resource
+    BytedanceProjectMapper projectListMapper;
+    @Autowired
+    private CorpWexinUtils corpWexinUtils;
+
+    /**
+     * 头条账户 出价预警
+     *
+     * @param accountId
+     */
+    @Override
+    public void byteDanceAccountWarning(Long accountId, Integer nowDate, Integer yesterda) {
+        try {
+            Integer maxHour = bytedanceAdvertiserHourlyReportMapper.selectMaxHour(accountId, nowDate);
+            if (Check.isNull(maxHour)) {
+                return;
+            }
+            UserAllocation userAllocation = userAllocationService.getByAccountId(accountId);
+            if (Check.isNull(userAllocation)) {
+                return;
+            }
+            Project project = userAllocationService.getProjectEntity(userAllocation.getProjectId());
+            if (userAllocation.getAccountStatus() == 1) {
+                return;
+            }
+            BigDecimal warningAmount = userAllocation.getWarningAmount();
+            BigDecimal warningProportion = userAllocation.getWarningProportion();
+            BigDecimal nowCost = bytedanceAdvertiserHourlyReportMapper.getCost(accountId, maxHour, nowDate);
+            BigDecimal cost = nowCost.setScale(2, RoundingMode.HALF_UP);
+            if (maxHour != 0) {
+                if (!Check.isNull(nowCost) && nowCost.compareTo(new BigDecimal(0)) != 0) {
+                    BigDecimal lastHourCost = bytedanceAdvertiserHourlyReportMapper.getCost(accountId, maxHour - 1, nowDate);
+                    if (!Check.isNull(lastHourCost) && lastHourCost.compareTo(new BigDecimal(0)) != 0) {
+                        BigDecimal subtract = nowCost.subtract(lastHourCost);
+                        BigDecimal divide = nowCost.divide(lastHourCost, 2, RoundingMode.HALF_UP);
+                        if (subtract.compareTo(warningAmount) > -1 && divide.compareTo(warningProportion) > -1) {
+                            sendMessage(accountId, userAllocation.getAuthName(), maxHour, cost, userAllocation.getProjectId(), project.getProjectName(), userAllocation.getUserName());
+                        }
+                    }
+                }
+            }
+
+            if (!Check.isNull(nowCost) && nowCost.compareTo(new BigDecimal(0)) != 0) {
+                BigDecimal yesterdayHourCost = bytedanceAdvertiserHourlyReportMapper.getCost(accountId, maxHour, yesterda);
+                if (!Check.isNull(yesterdayHourCost) && yesterdayHourCost.compareTo(new BigDecimal(0)) != 0) {
+                    BigDecimal subtract = nowCost.subtract(yesterdayHourCost);
+                    BigDecimal divide = nowCost.divide(yesterdayHourCost, 2, RoundingMode.HALF_UP);
+                    if (subtract.compareTo(warningAmount) > -1 && divide.compareTo(warningProportion) > -1) {
+                        sendYesterdayMessage(accountId, userAllocation.getAuthName(), maxHour, cost, userAllocation.getProjectId(), project.getProjectName(), userAllocation.getUserName());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private void sendYesterdayMessage(Long accountId, String authName, Integer maxHour, BigDecimal nowCost, Long projectId, String projectName, String userName) {
+        StringBuilder text = new StringBuilder();
+        text.append("较昨日同时段消耗预警").append("<br/>")
+                .append("您的项目:" + projectName + "下的,").append("<br/>")
+                .append("账号:").append(accountId + ",").append("授权名称为:" + authName).append("<br/>")
+                .append("账户所属人:" + userName).append("<br/>")
+                .append("相较于昨日 " + maxHour + "时").append("<br/>")
+                .append("出现消耗暴涨,").append("消耗金额为:" + nowCost).append("<br/>")
+                .append("请您及时查看!");
+        List<JSONObject> wexinIds = projectListMapper.getWChatIdsByAccountId(accountId);
+        corpWexinUtils.sendMessage(wexinIds, text.toString());
+
+    }
+
+    private void sendMessage(Long accountId, String authName, Integer hour, BigDecimal amount, Long projectId, String projectName, String userName) {
+        StringBuilder text = new StringBuilder();
+        text.append("较上时段消耗预警").append("<br/>")
+                .append("您的项目:" + projectName + " 下的").append("<br/>")
+                .append("账号:").append(accountId + ",").append("授权名称为:" + authName).append("<br/>")
+                .append("账户所属人:" + userName).append("<br/>")
+                .append(hour + " 时").append("相较于 " + (hour - 1) + " 时").append("<br/>")
+                .append("出现消耗暴涨,").append("消耗金额为:" + amount).append("<br/>")
+                .append("请您及时查看!");
+
+        List<JSONObject> wexinIds = projectListMapper.getWChatIdsByAccountId(accountId);
+        corpWexinUtils.sendMessage(wexinIds, text.toString());
+    }
+
+
+}

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

@@ -136,7 +136,7 @@ public class BytedanceProjectServiceImpl implements IBytedanceProjectService {
 
 
         for (int i = 0; i < data.size(); i++) {
         for (int i = 0; i < data.size(); i++) {
             JSONObject dataObject = data.getJSONObject(i);
             JSONObject dataObject = data.getJSONObject(i);
-//            System.out.println("账户ID:" + projectId + "数据:" + dataObject);
+            System.out.println("账户ID:" + projectId + "数据:" + dataObject);
             advertiserList.add(dataObject);
             advertiserList.add(dataObject);
         }
         }
 
 
@@ -179,7 +179,7 @@ public class BytedanceProjectServiceImpl implements IBytedanceProjectService {
             }
             }
             for (int i = 0; i < data.size(); i++) {
             for (int i = 0; i < data.size(); i++) {
                 JSONObject dataObject = data.getJSONObject(i);
                 JSONObject dataObject = data.getJSONObject(i);
-//                System.out.println("-------项目数据:" + dataObject);
+                System.out.println("-------项目数据:" + dataObject);
                 checkProjectBidType(oauthToken, date, dataObject);
                 checkProjectBidType(oauthToken, date, dataObject);
 
 
             }
             }

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

@@ -0,0 +1,150 @@
+package cn.com.ctop.job.bytedance.data.service.impl;
+
+import cn.com.ctop.job.bytedance.data.entity.Project;
+import cn.com.ctop.job.bytedance.data.entity.UserAllocation;
+import cn.com.ctop.job.bytedance.data.mapper.UserAllocationMapper;
+import cn.com.ctop.job.bytedance.data.service.IUserAllocationService;
+import cn.com.ctop.job.bytedance.data.utils.Check;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 用户分配
+ */
+@Service
+public class UserAllocationServiceImpl extends ServiceImpl<UserAllocationMapper, UserAllocation> implements IUserAllocationService {
+
+    @Autowired
+    UserAllocationMapper userAllocationMapper;
+
+    @Override
+    public UserAllocation getByAccountId(Long accountId) {
+        return userAllocationMapper.getOneByAccountId();
+    }
+
+    @Override
+    public List<UserAllocation> listByMediaId(String mediaId, int accountStatus) {
+        return userAllocationMapper.listByMediaId(mediaId, accountStatus);
+    }
+
+    @Override
+    public String getAdvertiserIdByAccountId(Long accountId) {
+        return userAllocationMapper.queryAdvertiserId(accountId);
+    }
+
+    @Override
+    public List<JSONObject> getAccountListByProject(Long projectId) {
+        return userAllocationMapper.getAccountListByProject(projectId);
+    }
+
+    /**
+     * 获取项目下的所有userId
+     *
+     * @param projectId
+     * @return
+     */
+    @Override
+    public List<JSONObject> getUserIdListByProjectId(Long projectId) {
+        return userAllocationMapper.getUserIdListByProjectId(projectId);
+    }
+
+    @Override
+    public List<JSONObject> getAccountIdListByUserId(String userId) {
+        return userAllocationMapper.getAccountIdListByUserId(userId);
+    }
+
+    @Override
+    public JSONObject getSwitchStatusByAccount(Long accountId) {
+        return userAllocationMapper.getSwitchStatusByAccount(accountId);
+    }
+
+    @Override
+    public List<Long> getAccountsByDeleteComment() {
+        return userAllocationMapper.queryAccountsByDeleteComment();
+    }
+
+    @Override
+    public List<UserAllocation> getAccountListByUserIdAndProductId(String userId, Long projectId, Long productId) {
+        return userAllocationMapper.getAccountListByUserIdAndProductId(userId, projectId, productId);
+    }
+
+    @Override
+    public Map<Long, List<JSONObject>> getAccountListByProjectList(List<JSONObject> projectList) {
+        Map<Long, List<JSONObject>> map = new HashMap<>();
+        List list = new ArrayList();
+        for (int i = 0; i < projectList.size(); i++) {
+            JSONObject jsonObject = projectList.get(i);
+            if (!Check.isNull(jsonObject)) {
+                list.add(jsonObject.getLong("projectId"));
+                map.put(jsonObject.getLong("projectId"), new ArrayList<>());
+            }
+        }
+        List<JSONObject> jsonList = userAllocationMapper.getAccountListByProjectList(list);
+        for (int i = 0; i < jsonList.size(); i++) {
+            JSONObject jsonObject = jsonList.get(i);
+            Long projectId = jsonObject.getLong("projectId");
+            List<JSONObject> jsonObjects = map.get(projectId);
+            jsonObjects.add(jsonObject);
+        }
+        return map;
+    }
+
+    @Override
+    public List<JSONObject> getUserIdListByProductId(Long productId) {
+        return userAllocationMapper.getUserIdListByProductId(productId);
+    }
+
+    @Override
+    public List<Long> getValidProjectIds(Integer mediaId) {
+        return userAllocationMapper.getValidProjectIds(mediaId);
+    }
+
+    @Override
+    public List<JSONObject> getByAccountIds(JSONArray accountIds) {
+        return userAllocationMapper.getByAccountIds(accountIds);
+    }
+
+    @Override
+    public List<Long> getKuaiShouUserIdListByProjectId(Long projectId) {
+        return userAllocationMapper.getKuaiShouUserIdListByProjectId(projectId);
+    }
+
+    @Override
+    public List<JSONObject> selectAccountsByKuaishouUserId(Long userId) {
+        return userAllocationMapper.selectAccountsByKuaishouUserId(userId);
+    }
+
+    @Override
+    public boolean updateProjectStrategyStatus(Long accountId, Integer projectStrategy) {
+        int num = userAllocationMapper.updateProjectStrategyStatus(accountId, projectStrategy);
+        return num > 0;
+    }
+
+    @Override
+    public List<Long> queryAutomaticAccounts(Long projectId) {
+        return userAllocationMapper.queryAutomaticAccounts(projectId);
+    }
+
+    @Override
+    public List<Long> getIdList() {
+        return userAllocationMapper.getIdList();
+    }
+
+    @Override
+    public JSONObject getProjectByAccountId(Long accountId) {
+        return baseMapper.getProjectByAccountId(accountId);
+    }
+
+    @Override
+    public Project getProjectEntity(Long projectId) {
+        return userAllocationMapper.getProjectEntity(projectId);
+    }
+}

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

@@ -26,6 +26,10 @@ public class DateUtils {
         return sdf.format(date);
         return sdf.format(date);
     }
     }
 
 
+    public static Integer getIntegerDate(String date) {
+        return Integer.valueOf(date.replace("-", ""));
+    }
+
 
 
     public static String getAnotherDay(String format, String date, Integer num) {
     public static String getAnotherDay(String format, String date, Integer num) {
 
 

+ 49 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceHourlyAccountWarningLoadJob.java

@@ -0,0 +1,49 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.data.service.IByteDanceHourlyAccountWarningService;
+import cn.com.ctop.job.bytedance.data.service.IOauthTokenService;
+import cn.com.ctop.job.bytedance.data.utils.DateUtils;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+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;
+
+/**
+ * 头条预警
+ *
+ * @author yumeng
+ */
+@Component
+public class ByteDanceHourlyAccountWarningLoadJob {
+    @Autowired
+    private IOauthTokenService tokenService;
+    @Autowired
+    private IByteDanceHourlyAccountWarningService byteDanceHourlyAccountWarningService;
+    static ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    /**
+     * 头条时段消耗预警
+     *
+     * @throws Exception
+     */
+    @XxlJob("byteDanceHourlyAccountWarning")
+    public void execute() throws Exception {
+        XxlJobHelper.log("开始时段消耗预警定时任务");
+        long startTime = System.currentTimeMillis();
+        List<Long> tokens = tokenService.getAllToutiaoAccountIds();
+        if (null == tokens || tokens.isEmpty()) {
+            XxlJobHelper.log("定时获取头条数据异常:未获取到可用的token");
+            XxlJobHelper.handleFail();
+            return;
+        }
+        String nowDateStr = DateUtils.getNowDate("yyyy-MM-dd");
+        Integer nowDateInt = DateUtils.getIntegerDate(nowDateStr);
+        Integer yesterdaInt = DateUtils.getIntegerDate(DateUtils.getAnotherDay("yyyy-MM-dd", nowDateStr, -1));
+        tokens.forEach(accountId -> executorService.submit(() -> byteDanceHourlyAccountWarningService.byteDanceAccountWarning(accountId, nowDateInt, yesterdaInt)));
+        XxlJobHelper.log("时段消耗预警定时任务执行完毕,耗时:{} ms", System.currentTimeMillis() - startTime);
+    }
+}