Ver código fonte

广告组 出价预警

zhaoxian 1 ano atrás
pai
commit
f9b2840fac

+ 1 - 1
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/controller/KuaishouController.java

@@ -131,7 +131,7 @@ public class KuaishouController {
         String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
         String token = tokenService.getByAccountId(accountId);
         //更新 组
-        adUnitReportService.getAdUnitReport(accountId, token, nowDate, nowDate, 1);
+        adUnitReportService.getAdUnitReport(accountId,null, token, nowDate, nowDate, 1);
         //更新 组时报
         unitReportHourlyService.getUnitReportHour(accountId, token, nowDate, nowDate, 1);
     }

+ 4 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/constant/KuaishouConstant.java

@@ -17,6 +17,10 @@ public class KuaishouConstant {
 
     //获取广告组信息
     public static final String AD_UNIT_LIST = "/rest/openapi/gw/dsp/unit/list";
+    /**
+     * 修改广告组状态
+     */
+    public static final String UPDATE_UNIT_STATUS = "/rest/openapi/v1/ad_unit/update/status";
 
     //获取广告计划信息
     public static final String CAMPAIGN_LIST = "/rest/openapi/v1/campaign/list";

+ 47 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/entity/MediaSendAlarmRecord.java

@@ -0,0 +1,47 @@
+package cn.com.ctop.job.kuaishou.data.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * @Description: 媒体预警发送表
+ */
+@Data
+@TableName("ctop_media_send_alarm_record")
+@Accessors(chain = true)
+@ApiModel(value = "ctop_media_send_alarm_record对象", description = "媒体预警发送表")
+public class MediaSendAlarmRecord {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long accountId;
+    private Long planId;
+    private Long projectId;
+    private String userId;
+    private String alarmDetail;
+    private String mediaType;
+    /**
+     * createTime
+     */
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    private Date updateTime;
+
+    public MediaSendAlarmRecord(Long accountId, String mediaType, String alarmDetail, Long projectId) {
+        this.accountId = accountId;
+        this.mediaType = mediaType;
+        this.alarmDetail = alarmDetail;
+        this.projectId = projectId;
+    }
+
+    public MediaSendAlarmRecord() {
+    }
+}

+ 18 - 9
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/AdUnitReportMapper.java

@@ -1,10 +1,14 @@
 package cn.com.ctop.job.kuaishou.data.mapper;
 
-import cn.com.ctop.job.kuaishou.data.entity.*;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import cn.com.ctop.job.kuaishou.data.entity.KuaiShouDailyAgent;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdUnitList;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouCampaignList;
+import cn.com.ctop.job.kuaishou.data.entity.MediaSendAlarmRecord;
+import com.alibaba.fastjson.JSONObject;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 快手-广告组信息
@@ -12,15 +16,20 @@ import java.util.List;
  * @author jeecg-boot 2021-09-07
  * @version V1.0
  */
-public interface AdUnitReportMapper{
+public interface AdUnitReportMapper {
 
-  //批量插入 快手-广告组信息
-  void replaceBatchKsAdUnit(@Param("addList") List<KuaishouAdUnitList> addList);
+    //批量插入 快手-广告组信息
+    void replaceBatchKsAdUnit(@Param("addList") List<KuaishouAdUnitList> addList);
 
-  //批量插入 快手-广告计划信息
-  void replaceBatchKsCampaign(@Param("addList") List<KuaishouCampaignList> addList);
+    //批量插入 快手-广告计划信息
+    void replaceBatchKsCampaign(@Param("addList") List<KuaishouCampaignList> addList);
 
-  //批量插入 快手-代理商数据
-  void replaceBatchAgentReport(@Param("addList") List<KuaiShouDailyAgent> addList);
+    //批量插入 快手-代理商数据
+    void replaceBatchAgentReport(@Param("addList") List<KuaiShouDailyAgent> addList);
 
+    JSONObject getBidTypeAndMaxBid(@Param("accountId") Long accountId);
+
+    void insertSendRecord(MediaSendAlarmRecord record);
+
+    void deleteByMap(Map<String, Object> deleteMap);
 }

+ 2 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/OauthTokenMapper.java

@@ -22,4 +22,6 @@ public interface OauthTokenMapper extends BaseMapper<OauthToken> {
     List<Long> getAllAccountIds();
 
     List<JSONObject> selectKuaiShouToken();
+
+    List<JSONObject> getKuaishouOcpxTypeList();
 }

+ 206 - 166
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/mapper/xml/AdUnitReportMapper.xml

@@ -4,174 +4,173 @@
 
     <!-- 插入 快手广告组信息 -->
     <insert id="replaceBatchKsAdUnit">
-       replace into kuaishou_ad_unit_list(
-       `campaign_id`,
-       `advertiser_id`,
-       `unit_id`,
-       `unit_name`,
-       `status`,
-       `put_status`,
-       `create_channel`,
-       `review_detail`,
-       `study_status`,
-       `compensate_status`,
-       `bid_type`,
-       `bid`,
-       `cpa_bid`,
-       `smart_bid`,
-       `ocpx_action_type`,
-       `deep_conversion_type`,
-       `deep_conversion_bid`,
-       `day_budget`,
-       `day_budget_schedule`,
-       `roi_ratio`,
-       `speed`,
-       `begin_time`,
-       `end_time`,
-       `schedule`,
-       `schedule_time`,
-       `scene_id`,
-       `show_mode`,
-       `unit_type`,
-       `convert_id`,
-       `use_app_market`,
-       `app_store`,
-       `url_type`,
-       `web_uri_type`,
-       `url`,
-       `schema_uri`,
-       `app_id`,
-       `app_icon_url`,
-       `diverse_data`,
-       `target`,
-       `site_type`,
-       `gift_data`,
-       `video_landing_page`,
-       `auto_target`,
-       `smart_cover`,
-       `asset_mining`,
-       `auto_create_photo`,
-       `update_time`,
-       `item_id`,
-       `fiction_id`,
-       `merchant_item_put_type`,
-       `consult_id`,
-       `adv_card_option`,
-       `adv_card_list`,
-       `adv_card_id`,
-       `card_type`,
-       `image_url`,
-       `title`,
-       `sub_title`,
-       `price`,
-       `sale_price`,
-       `backflow_forecast`,
-       `merchandise_id`,
-       `merchandise_type`,
-       `playable_orientation`,
-       `playable_url`,
-       `playable_file_name`,
-       `playable_switch`,
-       `playable_id`,
-       `play_button`,
-       `splash_ad_switch`,
-       `library_id`,
-       `outer_id`,
-       `product_name`,
-       `product_price`,
-       `product_image`,
-       `ention_target`,
-       `create_time`,
-       `unit_source`
-       )
-       values
-       <foreach collection="addList" item="add" separator=",">
-           (
-           #{add.campaignId},
-           #{add.advertiserId},
-           #{add.unitId},
-           #{add.unitName},
-           #{add.status},
-           #{add.putStatus},
-           #{add.createChannel},
-           #{add.reviewDetail},
-           #{add.studyStatus},
-           #{add.compensateStatus},
-           #{add.bidType},
-           #{add.bid},
-           #{add.cpaBid},
-           #{add.smartBid},
-           #{add.ocpxActionType},
-           #{add.deepConversionType},
-           #{add.deepConversionBid},
-           #{add.dayBudget},
-           #{add.dayBudgetSchedule},
-           #{add.roiRatio},
-           #{add.speed},
-           #{add.beginTime},
-           #{add.endTime},
-           #{add.schedule},
-           #{add.scheduleTime},
-           #{add.sceneId},
-           #{add.showMode},
-           #{add.unitType},
-           #{add.convertId},
-           #{add.useAppMarket},
-           #{add.appStore},
-           #{add.urlType},
-           #{add.webUriType},
-           #{add.url},
-           #{add.schemaUri},
-           #{add.appId},
-           #{add.appIconUrl},
-           #{add.diverseData},
-           #{add.target},
-           #{add.siteType},
-           #{add.giftData},
-           #{add.videoLandingPage},
-           #{add.autoTarget},
-           #{add.smartCover},
-           #{add.assetMining},
-           #{add.autoCreatePhoto},
-           #{add.updateTime},
-           #{add.itemId},
-           #{add.fictionId},
-           #{add.merchantItemPutType},
-           #{add.consultId},
-           #{add.advCardOption},
-           #{add.advCardList},
-           #{add.advCardId},
-           #{add.cardType},
-           #{add.imageUrl},
-           #{add.title},
-           #{add.subTitle},
-           #{add.price},
-           #{add.salePrice},
-           #{add.backflowForecast},
-           #{add.merchandiseId},
-           #{add.merchandiseType},
-           #{add.playableOrientation},
-           #{add.playableUrl},
-           #{add.playableFileName},
-           #{add.playableSwitch},
-           #{add.playableId},
-           #{add.playButton},
-           #{add.splashAdSwitch},
-           #{add.libraryId},
-           #{add.outerId},
-           #{add.productName},
-           #{add.productPrice},
-           #{add.productImage},
-           #{add.entionTarget},
-           #{add.createTime},
-           #{add.unitSource}
-           )
-       </foreach>
-   </insert>
-
+        replace into kuaishou_ad_unit_list(
+        `campaign_id`,
+        `advertiser_id`,
+        `unit_id`,
+        `unit_name`,
+        `status`,
+        `put_status`,
+        `create_channel`,
+        `review_detail`,
+        `study_status`,
+        `compensate_status`,
+        `bid_type`,
+        `bid`,
+        `cpa_bid`,
+        `smart_bid`,
+        `ocpx_action_type`,
+        `deep_conversion_type`,
+        `deep_conversion_bid`,
+        `day_budget`,
+        `day_budget_schedule`,
+        `roi_ratio`,
+        `speed`,
+        `begin_time`,
+        `end_time`,
+        `schedule`,
+        `schedule_time`,
+        `scene_id`,
+        `show_mode`,
+        `unit_type`,
+        `convert_id`,
+        `use_app_market`,
+        `app_store`,
+        `url_type`,
+        `web_uri_type`,
+        `url`,
+        `schema_uri`,
+        `app_id`,
+        `app_icon_url`,
+        `diverse_data`,
+        `target`,
+        `site_type`,
+        `gift_data`,
+        `video_landing_page`,
+        `auto_target`,
+        `smart_cover`,
+        `asset_mining`,
+        `auto_create_photo`,
+        `update_time`,
+        `item_id`,
+        `fiction_id`,
+        `merchant_item_put_type`,
+        `consult_id`,
+        `adv_card_option`,
+        `adv_card_list`,
+        `adv_card_id`,
+        `card_type`,
+        `image_url`,
+        `title`,
+        `sub_title`,
+        `price`,
+        `sale_price`,
+        `backflow_forecast`,
+        `merchandise_id`,
+        `merchandise_type`,
+        `playable_orientation`,
+        `playable_url`,
+        `playable_file_name`,
+        `playable_switch`,
+        `playable_id`,
+        `play_button`,
+        `splash_ad_switch`,
+        `library_id`,
+        `outer_id`,
+        `product_name`,
+        `product_price`,
+        `product_image`,
+        `ention_target`,
+        `create_time`,
+        `unit_source`
+        )
+        values
+        <foreach collection="addList" item="add" separator=",">
+            (
+            #{add.campaignId},
+            #{add.advertiserId},
+            #{add.unitId},
+            #{add.unitName},
+            #{add.status},
+            #{add.putStatus},
+            #{add.createChannel},
+            #{add.reviewDetail},
+            #{add.studyStatus},
+            #{add.compensateStatus},
+            #{add.bidType},
+            #{add.bid},
+            #{add.cpaBid},
+            #{add.smartBid},
+            #{add.ocpxActionType},
+            #{add.deepConversionType},
+            #{add.deepConversionBid},
+            #{add.dayBudget},
+            #{add.dayBudgetSchedule},
+            #{add.roiRatio},
+            #{add.speed},
+            #{add.beginTime},
+            #{add.endTime},
+            #{add.schedule},
+            #{add.scheduleTime},
+            #{add.sceneId},
+            #{add.showMode},
+            #{add.unitType},
+            #{add.convertId},
+            #{add.useAppMarket},
+            #{add.appStore},
+            #{add.urlType},
+            #{add.webUriType},
+            #{add.url},
+            #{add.schemaUri},
+            #{add.appId},
+            #{add.appIconUrl},
+            #{add.diverseData},
+            #{add.target},
+            #{add.siteType},
+            #{add.giftData},
+            #{add.videoLandingPage},
+            #{add.autoTarget},
+            #{add.smartCover},
+            #{add.assetMining},
+            #{add.autoCreatePhoto},
+            #{add.updateTime},
+            #{add.itemId},
+            #{add.fictionId},
+            #{add.merchantItemPutType},
+            #{add.consultId},
+            #{add.advCardOption},
+            #{add.advCardList},
+            #{add.advCardId},
+            #{add.cardType},
+            #{add.imageUrl},
+            #{add.title},
+            #{add.subTitle},
+            #{add.price},
+            #{add.salePrice},
+            #{add.backflowForecast},
+            #{add.merchandiseId},
+            #{add.merchandiseType},
+            #{add.playableOrientation},
+            #{add.playableUrl},
+            #{add.playableFileName},
+            #{add.playableSwitch},
+            #{add.playableId},
+            #{add.playButton},
+            #{add.splashAdSwitch},
+            #{add.libraryId},
+            #{add.outerId},
+            #{add.productName},
+            #{add.productPrice},
+            #{add.productImage},
+            #{add.entionTarget},
+            #{add.createTime},
+            #{add.unitSource}
+            )
+        </foreach>
+    </insert>
 
 
-<!-- 插入 快手广告计划信息 -->
+    <!-- 插入 快手广告计划信息 -->
     <insert id="replaceBatchKsCampaign">
         replace into kuaishou_campaign_list(
         `advertiser_id`,
@@ -268,4 +267,45 @@
 
     </insert>
 
+
+    <!-- 获取用户微信id -->
+    <select id="getBidTypeAndMaxBid" 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>
+
+    <insert id="insertSendRecord">
+        insert
+        into `jeecg-boot`.ctop_media_send_alarm_record
+        (account_id,
+         plan_id,
+         project_id,
+         user_id,
+         alarm_detail,
+         media_type)
+        values (#{accountId},
+                #{planId},
+                #{projectId},
+                #{userId},
+                #{alarmDetail},
+                #{mediaType})
+    </insert>
+
+    <delete id="deleteByMap">
+        delete
+        from kuaishou_ad_unit_list
+        where account_id = #{accountId}
+          AND unit_id#{unitId}
+    </delete>
 </mapper>

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

@@ -58,4 +58,10 @@
           AND t1.media_id = 2;
     </select>
 
+    <select id="getKuaishouOcpxTypeList" resultType="com.alibaba.fastjson.JSONObject">
+        select ocpx_action_type as 'ocpxActionType', ocpx_action_name as 'ocpxActionName'
+        from `jeecg-boot`.ctop_kuaishou_ocpx_action_type_config
+    </select>
+
+
 </mapper>

+ 10 - 10
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/IAdUnitReportService.java

@@ -1,11 +1,6 @@
 package cn.com.ctop.job.kuaishou.data.service;
 
-import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdUnitList;
-import cn.com.ctop.job.kuaishou.data.entity.OauthToken;
-import com.baomidou.mybatisplus.extension.service.IService;
-
 import java.util.List;
-import java.util.PrimitiveIterator;
 
 /**
  * 定时任务
@@ -14,9 +9,13 @@ import java.util.PrimitiveIterator;
  * 2022-01-05
  * @version V1.0
  */
-public interface IAdUnitReportService{
+public interface IAdUnitReportService {
+
+    void getAdUnitReport(Long advertiserId, Long unitId, String accessToken, String startDate, String endDate, int page);
 
-    void getAdUnitReport(Long advertiserId, String accessToken, String startDate, String endDate, int page);
+    void checkGroupInfo(Long advertiserId, String accessToken, String startDate, String endDate, int page);
+
+    void updateUnitStatus(String token, Long advertiserId, Long unitId, int putStatus );
 
     void getAdPlanReport(Long advertiserId, String accessToken, String startDate, String endDate, int page);
 
@@ -24,9 +23,10 @@ public interface IAdUnitReportService{
 
     void getKuaishouAccountAdSceneDaily(Long advertiserId, String accessToken, String startDate, String endDate, int page, String temporalGranularity, List<String> reportDims);
 
-    void crowdAnalysisReport(Long advertiserId, String accessToken, String date,  List<Long> campaignIds,List<Long> unitIds, List<String> reportDims,Integer page);
+    void crowdAnalysisReport(Long advertiserId, String accessToken, String date, List<Long> campaignIds, List<Long> unitIds, List<String> reportDims, Integer page);
+
+    void getKuaishouDailyFlows(Long advertiserId, String accessToken, String startDate, String endDate, int page);
 
-    void getKuaishouDailyFlows(Long advertiserId, String accessToken,String startDate,String endDate,int page);
+    void getKuaishouDailyFundGet(Long advertiserId, String accessToken);
 
-    void getKuaishouDailyFundGet(Long advertiserId,String accessToken);
 }

+ 29 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/IWarningOperationService.java

@@ -0,0 +1,29 @@
+package cn.com.ctop.job.kuaishou.data.service;
+
+import com.alibaba.fastjson.JSONObject;
+
+public interface IWarningOperationService {
+    /**
+     * 快手 出价方式 预警 && 操作
+     *
+     * @param projectId
+     * @param projectName
+     * @param advertiserId
+     * @param unitId
+     * @param unit_name
+     */
+    void kuaiShouWarningOperation(Long projectId, String projectName, Long advertiserId, Long unitId, String unit_name);
+
+
+    /**
+     * 出价 过高预警 && 操作
+     *
+     * @param projectId
+     * @param projectName
+     * @param advertiserId
+     * @param unitId
+     * @param unit_name
+     */
+
+    void kuaiShouBidWarningOperation(Long projectId, String projectName, Long advertiserId, Long unitId, String unit_name);
+}

+ 263 - 4
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/data/service/impl/AdUnitReportServiceImpl.java

@@ -1,9 +1,22 @@
 package cn.com.ctop.job.kuaishou.data.service.impl;
 
 import cn.com.ctop.job.kuaishou.data.constant.KuaishouConstant;
-import cn.com.ctop.job.kuaishou.data.entity.*;
-import cn.com.ctop.job.kuaishou.data.mapper.*;
+import cn.com.ctop.job.kuaishou.data.entity.KuaiShouDailyAgent;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAccountAdSceneReportDaily;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdUnitList;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdvertiserFundDailyFlows;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAdvertiserFundGet;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouAudienceReportDaily;
+import cn.com.ctop.job.kuaishou.data.entity.KuaishouCampaignList;
+import cn.com.ctop.job.kuaishou.data.entity.OauthAgentToken;
+import cn.com.ctop.job.kuaishou.data.mapper.AdUnitReportMapper;
+import cn.com.ctop.job.kuaishou.data.mapper.KuaishouAccountAdSceneReportDailyMapper;
+import cn.com.ctop.job.kuaishou.data.mapper.KuaishouAdvertiserFundDailyFlowsMapper;
+import cn.com.ctop.job.kuaishou.data.mapper.KuaishouAudienceReportDailyMapper;
+import cn.com.ctop.job.kuaishou.data.mapper.OauthAgentTokenMapper;
+import cn.com.ctop.job.kuaishou.data.mapper.OauthTokenMapper;
 import cn.com.ctop.job.kuaishou.data.service.IAdUnitReportService;
+import cn.com.ctop.job.kuaishou.data.service.IWarningOperationService;
 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;
@@ -19,6 +32,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * 快手 定时任务
@@ -52,6 +67,10 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
     private KuaishouAdvertiserFundDailyFlowsMapper fundDailyFlowsMapper;
 
 
+    @Resource
+    private IWarningOperationService warningOperationService;
+
+
     /**
      * 获取广告组信息
      *
@@ -62,7 +81,7 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
      * @param page
      */
     @Override
-    public void getAdUnitReport(Long advertiserId, String accessToken, String startDate, String endDate, int page) {
+    public void getAdUnitReport(Long advertiserId, Long unitId, String accessToken, String startDate, String endDate, int page) {
         JSONObject param = new JSONObject();
         param.put("advertiser_id", advertiserId);
         param.put("page_size", 500);
@@ -71,6 +90,9 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
             param.put("start_date", startDate);
             param.put("end_date", endDate);
         }
+        if (unitId != null) {
+            param.put("unit_id", unitId);
+        }
         Map<String, String> headers = new HashMap<>();
         headers.put("Access-Token", accessToken);
         headers.put("Content-Type", "application/json");
@@ -114,13 +136,250 @@ public class AdUnitReportServiceImpl implements IAdUnitReportService {
             toGet = false;
         }
         if (toGet) {
-            getAdUnitReport(advertiserId, accessToken, startDate, endDate, page + 1);
+            getAdUnitReport(advertiserId, null, accessToken, startDate, endDate, page + 1);
         } else {
             log.info("快手广告组数据获取完成:accountId:{}", advertiserId);
         }
 
     }
 
+    @Override
+    public void checkGroupInfo(Long accountId, String accessToken, String startDate, String endDate, int page) {
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", accountId);
+        param.put("page_size", 500);
+        param.put("page", page);
+        if (startDate != null && endDate != null) {
+            param.put("start_date", startDate);
+            param.put("end_date", endDate);
+        }
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Access-Token", accessToken);
+        headers.put("Content-Type", "application/json");
+
+        String result = HttpUtils.kuaiShouhttpPostRequest(postUrl + KuaishouConstant.AD_UNIT_LIST, param.toJSONString(), headers);
+        JSONObject resultJson = JSONObject.parseObject(result);
+        if (Check.isNull(resultJson)) {
+            log.error("accountId:{} =》=》=》AdUnitReportServiceImpl.checkGroupInfo返回广告组数据为空", accountId);
+            return;
+        }
+        Integer code = resultJson.getInteger("code");
+        String message = resultJson.getString("message");
+        if (null == code || code != 0) {
+            log.error("accountId:{} =》=》=》AdUnitReportServiceImpl.checkGroupInfo\n返回广告组数据异常,message:{}", accountId, message);
+            return;
+        }
+        JSONArray details = resultJson.getJSONObject("data").getJSONArray("details");
+        if (null == details || details.size() <= 0) {
+            return;
+        }
+
+        checkAndInsertGroup(accountId, details);
+        //是否有下一页
+        Boolean toGet = true;
+        if (details.size() < page) {
+            toGet = false;
+        }
+        if (toGet) {
+            getAdUnitReport(accountId, null, accessToken, startDate, endDate, page + 1);
+        } else {
+            log.info(" =》AdUnitReportServiceImpl.checkGroupInfo =》快手广告组数据获取完成:accountId:{}", accountId);
+        }
+
+    }
+
+    static ExecutorService executorBidTypeService = Executors.newFixedThreadPool(20);
+    static ExecutorService executorMaxBidService = Executors.newFixedThreadPool(5);
+
+    private void checkAndInsertGroup(Long accountId, JSONArray details) {
+        JSONObject project = adUnitReportMapper.getBidTypeAndMaxBid(accountId);
+        if (Check.isNull(project) || Check.isNull(details)) {
+            return;
+        }
+
+        // 最高出价
+        Long maxBid = project.getLong("maxBid");
+
+        //优化目标集
+        List<Integer> bidList = null;
+        String bidTypeStr = project.getString("bidType");
+        if (!Check.isNull(bidTypeStr)) {
+            bidList = JSONArray.parseArray(bidTypeStr, Integer.class);
+        }
+
+        //转化目标map
+        Map<Integer, Long> ocpxMap = new HashMap<>();
+        String ocpxTypeStr = project.getString("ocpxActionType");
+        if (!Check.isNull(ocpxTypeStr)) {
+            JSONArray ocpxArr = JSONArray.parseArray(ocpxTypeStr);
+            for (int i = 0; i < ocpxArr.size(); i++) {
+                JSONObject obj = ocpxArr.getJSONObject(i);
+                ocpxMap.put(obj.getInteger("ocpxCode"), obj.getLong("maxValue"));
+            }
+        }
+
+        //深度转化目标map
+        Map<Integer, Long> deepMap = new HashMap<>();
+        String deepTypeStr = project.getString("deepConversionType");
+        if (!Check.isNull(deepTypeStr)) {
+            JSONArray deepArr = JSONArray.parseArray(deepTypeStr);
+            for (int i = 0; i < deepArr.size(); i++) {
+                JSONObject obj = deepArr.getJSONObject(i);
+                ocpxMap.put(obj.getInteger("deepCode"), obj.getLong("deepValue"));
+            }
+        }
+        List<KuaishouAdUnitList> ksAdUnitList = new ArrayList<>();
+        for (int i = 0; i < details.size(); i++) {
+            JSONObject detail = JSONObject.parseObject(details.get(i).toString());
+            if (!Check.isNull(detail)) {
+                //优化目标
+                Integer bidType = detail.getInteger("bid_type");
+                //优化出价(只有单击时,才有值)
+                Long bid = detail.getLong("bid");
+                //转化目标
+                Integer ocpxActionType = detail.getInteger("ocpx_action_type");
+                //转化目标出价
+                Long cpaBid = detail.getLong("cpa_bid");
+                //深度转化目标
+                Integer deepConversionType = detail.getInteger("deep_conversion_type");
+                //深度转化目标出价
+                Long deepConversionBid = detail.getLong("deep_conversion_bid");
+                //单日预算
+                Long dayBudget = detail.getLong("day_budget");
+                //组ID
+                Long unitId = detail.getLong("unit_id");
+                //组名称
+                String unitName = detail.getString("unit_name");
+                //状态
+                Integer status = detail.getInteger("status");
+                //投放状态
+                Integer putStatus = detail.getInteger("put_status");
+                if (putStatus == 1 && status != 15) { // 组状态为 投放中的 and 广告组状态为非暂停
+                    Boolean typeFalg = true;
+                    Boolean bidFalg = true;
+
+                    //优化目标
+                    if (!bidList.isEmpty()) {
+                        if (!bidList.contains(bidType)) {
+                            //项目不包含该优化目标,则关停
+                            typeFalg = false;
+                        } else if (bidType == 2 && bid > maxBid) {
+                            //若优化目标为2点击数,并且广告组出价大于项目设置最大出价,则关停
+                            bidFalg = false;
+                        }
+                    }
+                    //转化目标
+                    if (!Check.isNull(ocpxActionType) && ocpxActionType != 0) {
+                        //!=0是设置过转化目标
+                        if (!Check.isNullMap(ocpxMap)) {
+                            Long ocpxBid = ocpxMap.get(ocpxActionType);
+                            if (Check.isNull(ocpxBid)) {
+                                if (ocpxActionType == 2 && dayBudget != 0 && dayBudget <= 500 * 1000) {
+                                    // 转化目标为2行为数,并且预算小于等于500且不是不限,则允许启动
+                                    typeFalg = true;
+                                }else{
+                                    //通过key未获取值,说明不包含该目标,进行关停
+                                    typeFalg = false;
+                                }
+                            } else {
+                                if (cpaBid > ocpxBid) {
+                                    //组转化出价 大于 项目设置最大转化出价,则关停
+                                    bidFalg = false;
+                                }
+                            }
+                        }else if (ocpxActionType == 2 && (dayBudget == 0 || dayBudget > 500 * 1000)) {
+                            // 转化目标为2行为数,并且预算大于500 或者不限,则关停
+                            typeFalg = false;
+                        }
+                    }
+
+                    //转化目标
+                    if (!Check.isNull(deepConversionType) && deepConversionType != 0 && !deepMap.isEmpty()) {
+                        Long deepBid = deepMap.get(deepConversionType);
+                        if (Check.isNull(deepBid)) {
+                            //通过key未获取值,说明不包含该目标,进行关停
+                            typeFalg = false;
+                        } else {
+                            if (deepConversionBid > deepBid) {
+                                //组深度转化出价 大于 项目设置最大转化出价,则关停
+                                bidFalg = false;
+                            }
+                        }
+                    }
+
+                    if (!typeFalg) { // 出价方式设置非法
+                        executorBidTypeService.submit(new Runnable() {
+                            @Override
+                            public void run() {
+                                warningOperationService.kuaiShouWarningOperation(project.getLong("projectId"), project.getString("projectName"), accountId, unitId, unitName);
+                            }
+                        });
+                    }
+                    if (!bidFalg) {
+                        executorMaxBidService.submit(new Runnable() {
+                            @Override
+                            public void run() {
+                                warningOperationService.kuaiShouBidWarningOperation(project.getLong("projectId"), project.getString("projectName"), accountId, unitId, unitName);
+                            }
+                        });
+                    }
+                }
+                for (Object deta : details) {
+                    JSONObject unitDetail = (JSONObject) deta;
+                    unitDetail.put("advertiser_id", accountId);
+                    KuaishouAdUnitList ksAdunit = KuaishouAdUnitList.getAdUnitListInfo(unitDetail);
+                    ksAdUnitList.add(ksAdunit);
+                }
+            }
+        }
+        if (!Check.isNull(ksAdUnitList)) {
+            adUnitReportMapper.replaceBatchKsAdUnit(ksAdUnitList);
+            log.info("组数据添加成功,accountId:{},条数:{}", accountId, ksAdUnitList.size());
+        }
+    }
+
+
+    /**
+     * 修改广告组状态
+     * putStatus 1-投放、2-暂停、3-删除,传其他数字非法
+     */
+    @Override
+    public void updateUnitStatus(String token, Long acccountId, Long unitId, int putStatus) {
+        try {
+            String url = postUrl + KuaishouConstant.UPDATE_UNIT_STATUS;
+            Map<String, String> header = new HashMap<>();
+            header.put("Access-Token", token);
+            header.put("Content-Type", "application/json");
+            JSONObject params = new JSONObject();
+            params.put("advertiser_id", acccountId);
+            params.put("unit_id", unitId);
+            params.put("put_status", putStatus);
+            String result = HttpUtils.httpPostRequest(url, params, header);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    if (putStatus == 3) {
+                        Map<String, Object> deleteMap = new HashMap<>();
+                        deleteMap.put("accountId", acccountId);
+                        deleteMap.put("unitId", unitId);
+                        adUnitReportMapper.deleteByMap(deleteMap);
+                    } else {
+                        getAdUnitReport(acccountId, null, token, null, null, 1);
+                    }
+                } else {
+                    log.error("=》=》=》AdUnitReportServiceImpl.updateUnitStatus修改广告组状态失败,advertiserId:{},unitId:{},返回信息:{}", acccountId, unitId, resultJson);
+                }
+            } else {
+                log.error("修改广告组状态返回结果为空,advertiserId:{},unitId:{}", acccountId, unitId);
+            }
+        } catch (Exception e) {
+            log.error("修改广告组状态异常,advertiserId:{},unitId:{}", acccountId, unitId);
+            e.printStackTrace();
+
+        }
+    }
+
     /**
      * 快手广告计划信息
      *

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

@@ -0,0 +1,104 @@
+package cn.com.ctop.job.kuaishou.data.service.impl;
+
+import cn.com.ctop.job.kuaishou.data.entity.MediaSendAlarmRecord;
+import cn.com.ctop.job.kuaishou.data.mapper.AdUnitReportMapper;
+import cn.com.ctop.job.kuaishou.data.service.IAdUnitReportService;
+import cn.com.ctop.job.kuaishou.data.service.IOauthTokenService;
+import cn.com.ctop.job.kuaishou.data.service.IWarningOperationService;
+import cn.com.ctop.job.kuaishou.data.service.IWexinConfigService;
+import cn.com.ctop.job.kuaishou.data.utils.weixin.CorpWexinUtils;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Slf4j
+@Service
+public class WarningOperationServiceImpl implements IWarningOperationService {
+    @Autowired
+    private IOauthTokenService tokenService;
+    @Autowired
+    private IAdUnitReportService unitReportService;
+    @Resource
+    private AdUnitReportMapper adUnitReportMapper;
+    @Autowired
+    private CorpWexinUtils corpWexinUtils;
+    @Resource
+    private IWexinConfigService wexinService;
+
+    /**
+     * 快手出价方式预警 && 操作
+     *
+     * @param projectId
+     * @param projectName
+     * @param accountId
+     * @param unitId
+     * @param unit_name
+     */
+
+    @Override
+    public void kuaiShouWarningOperation(Long projectId, String projectName, Long accountId, Long unitId, String unit_name) {
+        String token = tokenService.getByAccountId(accountId);
+        unitReportService.updateUnitStatus(token, accountId, unitId, 2);
+        String text = getKuaiShouBidTypeMessage(projectName, accountId, unitId, unit_name);
+        //日志记录
+        MediaSendAlarmRecord record = new MediaSendAlarmRecord(accountId, "2", text, unitId);
+        adUnitReportMapper.insertSendRecord(record);
+
+        List<JSONObject> wexinIds = wexinService.selectUsersByAccountId(accountId);
+        corpWexinUtils.sendMessage(wexinIds, text);
+    }
+
+    private String getKuaiShouBidTypeMessage(String projectName, Long advertiserId, Long unitId, String unit_name) {
+        StringBuilder text = new StringBuilder();
+        text.append("出价方式错误预警").append("<br/>")
+                .append("您的项目:").append(projectName + ",").append("<br/>")
+                .append("下的账户:").append(advertiserId + ",").append("<br/>")
+                .append("广告组id为:").append(unitId).append("<br/>")
+                .append("广告组名称为:").append(unit_name).append("<br/>")
+                .append("出价方式设置错误。").append("<br/>")
+                .append("系统已执行暂停此组操作,请您及时查看!");
+        return text.toString();
+    }
+
+
+    /**
+     * 出价 过高预警 && 操作
+     *
+     * @param projectId
+     * @param projectName
+     * @param accountId
+     * @param unitId
+     * @param unit_name
+     */
+
+    @Override
+    public void kuaiShouBidWarningOperation(Long projectId, String projectName, Long accountId, Long unitId, String unit_name) {
+
+        String token = tokenService.getByAccountId(accountId);
+        unitReportService.updateUnitStatus(token, accountId, unitId, 2);
+
+        //日志记录
+        String text = getKuaiShouBidMessage(projectName, accountId, unitId, unit_name);
+        MediaSendAlarmRecord record = new MediaSendAlarmRecord(accountId, "2", text, unitId);
+        adUnitReportMapper.insertSendRecord(record);
+
+        List<JSONObject> wexinIds = wexinService.selectUsersByAccountId(accountId);
+        corpWexinUtils.sendMessage(wexinIds, text);
+    }
+
+    private String getKuaiShouBidMessage(String projectName, Long advertiserId, Long unitId, String unit_name) {
+        StringBuilder text = new StringBuilder();
+        text.append("出价过高预警").append("<br/>")
+                .append("您的项目:").append(projectName + ",").append("<br/>")
+                .append("下的账户:").append(advertiserId + ",").append("<br/>")
+                .append("广告组id为:").append(unitId).append("<br/>")
+                .append("广告组名称为:").append(unit_name).append("<br/>")
+                .append("出价设置过高。").append("<br/>")
+                .append("系统已执行暂停此组操作,请您及时查看!");
+        return text.toString();
+    }
+}

+ 2 - 2
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/AdUnitReportJob.java

@@ -56,7 +56,7 @@ public class AdUnitReportJob {
                 new Runnable() {
                     @Override
                     public void run() {
-                        adUnitReportService.getAdUnitReport(Long.valueOf(param), token, endTime, endTime, 1);
+                        adUnitReportService.getAdUnitReport(Long.valueOf(param), null, token, endTime, endTime, 1);
                     }
                 });
     }
@@ -87,7 +87,7 @@ public class AdUnitReportJob {
                     @Override
                     public void run() {
                         try {
-                            adUnitReportService.getAdUnitReport(Long.valueOf(param), token, startTime, startTime, 1);
+                            adUnitReportService.getAdUnitReport(Long.valueOf(param), null, token, startTime, startTime, 1);
                         } catch (Exception e) {
                             log.info(String.valueOf(e));
                             ;

+ 58 - 0
job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaishouGroupJob.java

@@ -0,0 +1,58 @@
+package cn.com.ctop.job.kuaishou.handler;
+
+import cn.com.ctop.job.kuaishou.data.service.IAdUnitReportService;
+import cn.com.ctop.job.kuaishou.data.service.IKuaishouUnitReportDailyService;
+import cn.com.ctop.job.kuaishou.data.service.IOauthTokenService;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Component
+public class KuaishouGroupJob {
+    @Autowired
+    private IOauthTokenService tokenService;
+    @Autowired
+    private IAdUnitReportService unitReportService;
+
+    private static ExecutorService dailyExecutorService = Executors.newFixedThreadPool(3);
+
+    /**
+     * 快手广告组物料
+     *
+     * @throws Exception
+     */
+    @XxlJob("kuaishouGroup")
+    public void execute() throws Exception {
+        String param = XxlJobHelper.getJobParam(); // 执行参数
+        if (Check.isNull(param)) {
+            log.error("入参为空");
+            return;
+        }
+        String token = tokenService.getByAccountId(Long.valueOf(param));
+        if (Check.isNull(token)) {
+            log.error("此账户未获取到相关token,accountId:{}", param);
+            return;
+        }
+        String today = DateUtils.getNowDate("yyyy-MM-dd");
+        String yesterday = DateUtils.getAnotherDay("yyyy-MM-dd", DateUtils.getNowDate("yyyy-MM-dd"), -1);
+        dailyExecutorService.submit(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        unitReportService.checkGroupInfo(Long.valueOf(param), token, yesterday, yesterday, 1);
+                    }
+                });
+    }
+
+}