浏览代码

消耗预警

yumeng 5 年之前
父节点
当前提交
3371ff8028
共有 14 个文件被更改,包括 441 次插入136 次删除
  1. 77 56
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java
  2. 68 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/ByteDanceHourlyAccountWarningLoadJob.java
  3. 19 8
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedanceHourlyReportLoadJob.java
  4. 1 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/KuaishouHourlyAccountReportLoadJob.java
  5. 12 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/KuaishouHourlyAccountWarningLoadJob.java
  6. 27 61
      jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java
  7. 2 1
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IAccountWarningService.java
  8. 12 4
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/AccountWarningServiceImpl.java
  9. 16 2
      module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceAdvertiserHourlyReport.java
  10. 5 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceAdvertiserHourlyReportMapper.java
  11. 22 0
      module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceAdvertiserHourlyReportMapper.xml
  12. 5 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/IByteDanceHourlyAccountWarningService.java
  13. 174 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/ByteDanceHourlyAccountWarningServiceImpl.java
  14. 1 0
      module-report/src/main/java/cn/com/ctop/bytedance/service/impl/ReportServiceImpl.java

+ 77 - 56
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java

@@ -25,6 +25,24 @@ public class DateUtils extends PropertyEditorSupport {
     private static final long MINUTE_IN_MILLIS = 60 * 1000;
     private static final long SECOND_IN_MILLIS = 1000;
 
+    public static String getDateByDateStr(String dateStr) throws ParseException {
+        SimpleDateFormat dsdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date parse = dsdf.parse(dateStr);
+        String day = dsdf.format(parse);
+        return day;
+    }
+
+    public static Integer getHour(String dateStr) throws ParseException {
+        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Calendar cal = Calendar.getInstance();
+        Date date = sdf.parse(dateStr);
+        cal.setTime(date);
+        Integer hour = cal.get(Calendar.HOUR_OF_DAY);
+        return hour;
+
+
+    }
+
     /**
      * 指定模式的时间格式
      *
@@ -576,6 +594,7 @@ public class DateUtils extends PropertyEditorSupport {
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
         return dateFormat.format(getDate);
     }
+
     /**
      * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
      * HH:mm:ss“ * @param text String类型的时间值
@@ -904,21 +923,22 @@ public class DateUtils extends PropertyEditorSupport {
     /**
      * 根据时间获取季度
      * 1即Q1(1,2,3月),以此类推
+     *
      * @param date
      * @return
      */
-    public static int getQuarter(Date date){
+    public static int getQuarter(Date date) {
         Calendar cal = Calendar.getInstance();
         cal.setTime(date);
         //获取当前月份
         int month = cal.get(Calendar.MONTH) + 1;
-        if(month<=3){
+        if (month <= 3) {
             return 1;
-        }else if(month <=6){
+        } else if (month <= 6) {
             return 2;
-        }else if(month<=9){
+        } else if (month <= 9) {
             return 3;
-        }else if(month<=12){
+        } else if (month <= 12) {
             return 4;
         }
 
@@ -927,9 +947,10 @@ public class DateUtils extends PropertyEditorSupport {
 
     /**
      * 获取【所在周】周五的时间(周五为一周第一天,周四为一周最后一天)
+     *
      * @param date
      */
-    public static Date getFriday(Date date){
+    public static Date getFriday(Date date) {
         Calendar calendar = new GregorianCalendar();
         calendar.setTime(date);
         calendar.setFirstDayOfWeek(Calendar.FRIDAY);
@@ -943,8 +964,8 @@ public class DateUtils extends PropertyEditorSupport {
      * 获取传入时间的年、月份和季度(周五为每周第一天,周四为每周最后一天)
      * 获取的是所属年、月、季度,因为很多月份的第一周或最后 一周会包括上一个月或者下一个月的部分日期
      */
-    public static Map<String,Integer> getYearQuarter(Date date){
-        Map<String,Integer> dateMap = new HashMap<>();
+    public static Map<String, Integer> getYearQuarter(Date date) {
+        Map<String, Integer> dateMap = new HashMap<>();
 
         Calendar calendar = new GregorianCalendar();
         calendar.setTime(date);
@@ -971,63 +992,63 @@ public class DateUtils extends PropertyEditorSupport {
         int thursdayQuarter = DateUtils.getQuarter(calendar2.getTime());
 
         //如果本周第一天(周五)和当前天不在一个月内,说明周跨月了
-        if(fridayMonth == originMonth && thursdayMonth == originMonth){
+        if (fridayMonth == originMonth && thursdayMonth == originMonth) {
             dateMap.put("year", originYear);
             dateMap.put("month", originMonth + 1);  //最后一个月是11,应该+1
             dateMap.put("quarter", originQuarter);
             return dateMap;
-        }else if(fridayYear < originYear || (fridayYear ==originYear && fridayMonth < originMonth) ){
+        } else if (fridayYear < originYear || (fridayYear == originYear && fridayMonth < originMonth)) {
             //判断本周有几天在本月,如果是(5,6,7)则就是本月本季度
             //int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
             calendar1.set(Calendar.DATE, calendar1.getActualMaximum(Calendar.DATE));
             int lastDateWeek = calendar1.get(Calendar.DAY_OF_WEEK);
             //判断如果本周所在上个月的最后一天是周五、周六、周日的话,说明本周归属于本月(周五是第一天);否则本周归属于上个季度
-            if(lastDateWeek ==6 || lastDateWeek ==7 || lastDateWeek ==1 ){
+            if (lastDateWeek == 6 || lastDateWeek == 7 || lastDateWeek == 1) {
                 dateMap.put("year", originYear);
                 dateMap.put("month", originMonth + 1);
-                dateMap.put("quarter",originQuarter);
-            }else{
+                dateMap.put("quarter", originQuarter);
+            } else {
                 //判断如果本周属于上个月,判断是否跨年
-                if(originYear == fridayYear){
+                if (originYear == fridayYear) {
                     dateMap.put("year", originYear);
                     dateMap.put("month", originMonth);
                     //判断是否跨季
-                    if(originQuarter == fridayQuarter){
-                        dateMap.put("quarter",originQuarter);
-                    }else{
-                        dateMap.put("quarter",fridayQuarter);
+                    if (originQuarter == fridayQuarter) {
+                        dateMap.put("quarter", originQuarter);
+                    } else {
+                        dateMap.put("quarter", fridayQuarter);
                     }
-                }else{
+                } else {
                     //跨年的话说明这周上年的12月(第四季度)
-                    dateMap.put("year", originYear-1);
+                    dateMap.put("year", originYear - 1);
                     dateMap.put("month", 12); //??查看是11,还是12
-                    dateMap.put("quarter",4);
+                    dateMap.put("quarter", 4);
                 }
             }
             return dateMap;
-        }else if(originYear < thursdayYear || (originYear == thursdayYear && originMonth < thursdayMonth) ){
+        } else if (originYear < thursdayYear || (originYear == thursdayYear && originMonth < thursdayMonth)) {
             calendar2.set(Calendar.DATE, 1);
             int firstDateWeek = calendar2.get(Calendar.DAY_OF_WEEK);
             //如果跨月的第一天是周二周三周四的话说明这周不跨月,否在进入下个月(季度、年需要再判断)
-            if( firstDateWeek==3 || firstDateWeek==4 || firstDateWeek==5){
+            if (firstDateWeek == 3 || firstDateWeek == 4 || firstDateWeek == 5) {
                 dateMap.put("year", originYear);
-                dateMap.put("month", originMonth+1);
-                dateMap.put("quarter",originQuarter);
-            }else{
-                if( originYear == thursdayYear ){
+                dateMap.put("month", originMonth + 1);
+                dateMap.put("quarter", originQuarter);
+            } else {
+                if (originYear == thursdayYear) {
                     dateMap.put("year", originYear);
                     dateMap.put("month", originMonth + 1 + 1);
                     //判断是否跨季
-                    if(originQuarter == thursdayQuarter){
-                        dateMap.put("quarter",originQuarter);
-                    }else{
-                        dateMap.put("quarter",thursdayQuarter);
+                    if (originQuarter == thursdayQuarter) {
+                        dateMap.put("quarter", originQuarter);
+                    } else {
+                        dateMap.put("quarter", thursdayQuarter);
                     }
-                }else{
+                } else {
                     //跨年的话说明这周属于明年的1月(第一季度)
-                    dateMap.put("year", originYear+1);
+                    dateMap.put("year", originYear + 1);
                     dateMap.put("month", 1);
-                    dateMap.put("quarter",1);
+                    dateMap.put("quarter", 1);
                 }
             }
             return dateMap;
@@ -1038,11 +1059,12 @@ public class DateUtils extends PropertyEditorSupport {
     /**
      * 计算季度开始、结束时间
      * 原则:周五为本周的第一天,下一周的周四为本周的最后一天
+     *
      * @param year
      * @param quarter
      */
-    public static Map<String,String> quarterStartEndDate(int year, int quarter){
-        Map<String,String> quarterStartEndDateMap = new HashMap<>();
+    public static Map<String, String> quarterStartEndDate(int year, int quarter) {
+        Map<String, String> quarterStartEndDateMap = new HashMap<>();
 
         Date startDate = null;
         Date endDate = null;
@@ -1050,51 +1072,51 @@ public class DateUtils extends PropertyEditorSupport {
         int startMonth = 0;
         int endMonth = 0;
 
-        if(quarter == 1){
+        if (quarter == 1) {
             startMonth = 1;
             endMonth = 3;
-        }else if(quarter == 2){
+        } else if (quarter == 2) {
             startMonth = 4;
             endMonth = 6;
-        }else if(quarter == 3){
+        } else if (quarter == 3) {
             startMonth = 7;
             endMonth = 9;
-        }else{
+        } else {
             startMonth = 10;
             endMonth = 12;
         }
 
         //判断季度第一天的时间(以周为单位,有可能是上个月,也有可能是本月的非1号)
         Calendar calendar1 = new GregorianCalendar();
-        calendar1.set(Calendar.YEAR,year);
-        calendar1.set(Calendar.MONTH,startMonth-1);
-        calendar1.set(Calendar.DATE,1);
+        calendar1.set(Calendar.YEAR, year);
+        calendar1.set(Calendar.MONTH, startMonth - 1);
+        calendar1.set(Calendar.DATE, 1);
         calendar1.setFirstDayOfWeek(Calendar.FRIDAY);
 
         //如果季度第一个月的第一天是周二周三周四,那么这周应该归属于上个季度,否则这周(包括上个月的时间)归属于这个季度
         int firstDateWeek = calendar1.get(Calendar.DAY_OF_WEEK);
-        if(firstDateWeek ==5 || firstDateWeek ==3 || firstDateWeek ==4 ){
+        if (firstDateWeek == 5 || firstDateWeek == 3 || firstDateWeek == 4) {
             calendar1.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
-            startDate = DateUtils.addDay(calendar1.getTime(),1);
-        }else{
+            startDate = DateUtils.addDay(calendar1.getTime(), 1);
+        } else {
             calendar1.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
             startDate = calendar1.getTime();
         }
 
         //判断季度最后一天的时间(以周为单位,有可能是下个月,也有可能是本月的非最后一天)
         Calendar calendar2 = new GregorianCalendar();
-        calendar2.set(Calendar.YEAR,year);
-        calendar2.set(Calendar.MONTH,endMonth-1);
-        calendar2.set(Calendar.DATE,1);
+        calendar2.set(Calendar.YEAR, year);
+        calendar2.set(Calendar.MONTH, endMonth - 1);
+        calendar2.set(Calendar.DATE, 1);
         calendar2.setFirstDayOfWeek(Calendar.FRIDAY);
 
         //如果一个季度最后一个月最后一天是周五、周六、周日,则这个月最后一周属于下个季度
         calendar2.set(Calendar.DATE, calendar2.getActualMaximum(Calendar.DATE));
         int lastDateWeek = calendar2.get(Calendar.DAY_OF_WEEK);
-        if(lastDateWeek ==1 || lastDateWeek ==7 || lastDateWeek ==6){
+        if (lastDateWeek == 1 || lastDateWeek == 7 || lastDateWeek == 6) {
             calendar2.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
-            endDate = DateUtils.addDay(calendar2.getTime(),-1);
-        }else{
+            endDate = DateUtils.addDay(calendar2.getTime(), -1);
+        } else {
             calendar2.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
             endDate = calendar2.getTime();
         }
@@ -1118,16 +1140,15 @@ public class DateUtils extends PropertyEditorSupport {
         //Date effiStart = DateUtils.addDay(friDay,  -15);
         //System.out.println(sdf.format(effiStart));
 
-        Map<String,Integer> map1 = DateUtils.getYearQuarter(DateUtils.parseDate("2020-04-01","yyyy-MM-dd"));
+        Map<String, Integer> map1 = DateUtils.getYearQuarter(DateUtils.parseDate("2020-04-01", "yyyy-MM-dd"));
 
-        Map<String,String> map2 = DateUtils.quarterStartEndDate(2019,1);
+        Map<String, String> map2 = DateUtils.quarterStartEndDate(2019, 1);
 
-        for(String key:map2.keySet()){
+        for (String key : map2.keySet()) {
             System.out.println(key + ":" + map2.get(key));
         }
 
 
-
     }
 
 }

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

@@ -0,0 +1,68 @@
+package org.jeecg.modules.ctop.job;
+
+import cn.com.ctop.bytedance.service.IByteDanceHourlyAccountWarningService;
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.jeecg.common.util.DateUtils.getAnotherDay;
+
+/**
+ * 头条预警
+ *
+ * @author yumeng
+ */
+@Slf4j
+public class ByteDanceHourlyAccountWarningLoadJob implements Job {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IByteDanceHourlyAccountWarningService byteDanceHourlyAccountWarningService;
+    static ExecutorService executorService = null;
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                log.info("开始时段消耗预警定时任务");
+                long l = System.currentTimeMillis();
+                try {
+                    List<CtopOauthToken> tokens = tokenService.getTokenListByType(CtopAdConstant.PLATFORM_TYPE_BYTEDANCE);
+                    if (null == tokens || tokens.size() <= 0) {
+                        log.info("定时获取头条数据异常:未获取到可用的token");
+                        return;
+                    }
+                    executorService = Executors.newFixedThreadPool(3);
+                    String statDate = DateUtils.getDate("yyyy-MM-dd");
+                    String anotherDay = getAnotherDay("yyyy-MM-dd", statDate, -1);
+                    for (CtopOauthToken token : tokens) {
+                        executorService.submit(new Runnable() {
+                            @Override
+                            public void run() {
+                                byteDanceHourlyAccountWarningService.byteDanceAccountWarning(token.getAccountId(), statDate, anotherDay);
+                            }
+
+                        });
+                    }
+                    log.info("时段消耗预警定时任务执行完毕,耗时:{} ms", System.currentTimeMillis() - l);
+
+                } catch (Exception e) {
+                    e.printStackTrace();
+
+                }
+            }
+        };
+        thread.start();
+    }
+}

+ 19 - 8
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/BytedanceHourlyReportLoadJob.java

@@ -14,6 +14,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * @author syh
@@ -24,6 +26,7 @@ public class BytedanceHourlyReportLoadJob implements Job {
     private ICtopOauthTokenService tokenService;
     @Autowired
     private IReportService reportService;
+    static ExecutorService executorService = null;
 
     @Override
     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
@@ -39,16 +42,24 @@ public class BytedanceHourlyReportLoadJob implements Job {
             log.info("定时获取头条小时数据异常:未获取到可用的token");
             return;
         }
+        executorService = Executors.newFixedThreadPool(4);
         Date finalGetDate = getDate;
         tokens.forEach(token -> {
-            //1: 获取广告主信息数据
-            reportService.getAdvertiserReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
-            //2:获取广告组信息数据
-            //reportService.getAdvertiserCampaignReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
-            //3:获取广告计划信息数据
-            //reportService.getAdvertiserPlanReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
-            //4: 获取广告创意信息数据
-            //reportService.getAdvertiserCreativeReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+            executorService.submit(new Runnable() {
+                @Override
+                public void run() {
+                    //1: 获取广告主信息数据
+                    reportService.getAdvertiserReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+                    //2:获取广告组信息数据
+                    //reportService.getAdvertiserCampaignReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+                    //3:获取广告计划信息数据
+                    //reportService.getAdvertiserPlanReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+                    //4: 获取广告创意信息数据
+                    //reportService.getAdvertiserCreativeReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+                }
+
+            });
+
         });
     }
 }

+ 1 - 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/job/KuaishouHourlyAccountReportLoadJob.java

@@ -51,7 +51,7 @@ public class KuaishouHourlyAccountReportLoadJob implements Job {
                     log.info("定时获取快手数据异常:未获取到可用的token");
                     return;
                 }
-                executorService = Executors.newFixedThreadPool(3);
+                executorService = Executors.newFixedThreadPool(5);
                 countDownLatch = new CountDownLatch(tokens.size());
                 Date finalGetDate = getDate;
                 tokens.forEach(token -> {

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

@@ -12,6 +12,8 @@ import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 import static org.jeecg.common.util.DateUtils.getAnotherDay;
 
@@ -26,6 +28,7 @@ public class KuaishouHourlyAccountWarningLoadJob implements Job {
     private ICtopOauthTokenService tokenService;
     @Autowired
     private IAccountWarningService accountWarningService;
+    static ExecutorService executorService = null;
 
     @Override
     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
@@ -42,11 +45,17 @@ public class KuaishouHourlyAccountWarningLoadJob implements Job {
                     }
                     String statDate = DateUtils.getDate("yyyy-MM-dd");
                     String anotherDay = getAnotherDay("yyyy-MM-dd", statDate, -1);
-
+                    executorService = Executors.newFixedThreadPool(3);
                     for (CtopOauthToken token : tokens) {
-                        accountWarningService.accountWarning(token.getAccountId(), statDate, anotherDay);
+                        executorService.submit(new Runnable() {
+                            @Override
+                            public void run() {
+                                accountWarningService.kuaiShouAccountWarning(token.getAccountId(), statDate, anotherDay);
+
+                            }
+                        });
                     }
-                    log.info("时段消耗预警定时任务执行完毕,耗时:{} ms", System.currentTimeMillis() - l);
+                    log.info("异步时段消耗预警定时任务执行完毕,耗时:{} ms", System.currentTimeMillis() - l);
 
                 } catch (Exception e) {
                     e.printStackTrace();

+ 27 - 61
jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java

@@ -1,5 +1,6 @@
 package org.jeecg;
 
+import cn.com.ctop.bytedance.service.IByteDanceHourlyAccountWarningService;
 import cn.com.ctop.bytedance.service.IReportService;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.mapper.CtopOauthTokenMapper;
@@ -13,6 +14,7 @@ import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.http.impl.client.BasicCookieStore;
+import org.jeecg.common.util.DateUtils;
 import org.jeecg.modules.ctop.service.IBidWarningService;
 import org.jeecg.modules.ctop.service.ICreateInternalService;
 import org.jeecg.modules.mq.Sender;
@@ -181,78 +183,42 @@ public class SampleTest {
     private ICtopOauthTokenService tokenService;
     @Autowired
     private IReportService reportService;
-
+@Autowired
+private IByteDanceHourlyAccountWarningService byteDanceHourlyAccountWarningService;
     @Test
     public void testMa2() throws Exception {
 
-       /* QueryWrapper<CtopOauthToken> oauthTokenQueryWrapper = new QueryWrapper<>();
-        oauthTokenQueryWrapper.eq("media_id", 2);
-        List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(oauthTokenQueryWrapper);
-        for (CtopOauthToken token : ctopOauthTokens) {
-            executorService.submit(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        kuaishouInterfaceService.getCreativeList(token, null, null);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-            });
-        }*/
-
-
-       /* SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
-        Date parse = dateFormat.parse("2020-01-05");
-
-
-        QueryWrapper<CtopOauthToken> oauthTokenQueryWrapper = new QueryWrapper<>();
-        oauthTokenQueryWrapper.eq("media_id", 2);
-        List<Long> list = new ArrayList<>();
-        list.add(3162138L);
-        list.add(3418818L);
-        oauthTokenQueryWrapper.in("account_id", list);
-        List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(oauthTokenQueryWrapper);
-        for (CtopOauthToken token : ctopOauthTokens) {
-            kuaishouInterfaceService.getAdvertiserCreativeReportDaily(token, parse, parse);
 
+        byteDanceHourlyAccountWarningService.byteDanceAccountWarning(1655337394471943L,"2020-02-06","2020-02-05");
+        /*Date getDate = new Date();
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH");
+        String hour = simpleDateFormat.format(getDate);
+        if (null != hour && "00".equals(hour)) {
+            getDate = DateUtils.addDay(getDate, -1);
         }
-*/
-
-
-     /*   Date deleteDate = DateUtils.addDay(new Date(), -2);
-        kuaishouInterfaceService.deleteHourlyReport(deleteDate);
-        Date getDate = DateUtils.addDay(new Date(), -1);*/
         //1:查询当日数据
+        List<CtopOauthToken> tokens = tokenService.getTokenListByType(CtopAdConstant.PLATFORM_TYPE_BYTEDANCE);
+        if (null == tokens || tokens.size() <= 0) {
+            log.info("定时获取头条小时数据异常:未获取到可用的token");
+            return;
+        }
+        Date finalGetDate = getDate;
 
 
+        QueryWrapper<CtopOauthToken> oauthTokenQueryWrapper = new QueryWrapper<>();
+        oauthTokenQueryWrapper.eq("account_id", 1655337394471943L);
+        CtopOauthToken ctopOauthToken = oauthTokenMapper.selectOne(oauthTokenQueryWrapper);*/
 
-        //1: 获取广告主信息数据
-
-
-        // Date getDate = DateUtils.addDay(new Date(), -1);
 
-        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
-        Date parse = simpleDateFormat.parse("2020-01-09");
+        //1: 获取广告主信息数据
+          //  reportService.getAdvertiserReport(ctopOauthToken, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+            //2:获取广告组信息数据
+            //reportService.getAdvertiserCampaignReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+            //3:获取广告计划信息数据
+            //reportService.getAdvertiserPlanReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
+            //4: 获取广告创意信息数据
+            //reportService.getAdvertiserCreativeReport(token, finalGetDate, finalGetDate, CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY);
 
-        //1:查询当日数据
-        List<CtopOauthToken> tokens = tokenService.getTokenListByType(CtopAdConstant.PLATFORM_TYPE_BYTEDANCE);
-        if (null == tokens || tokens.size() <= 0) {
-            log.info("定时获取头条数据异常:为获取到可用的token");
-            return;
-        }
-        for (CtopOauthToken token : tokens) {
-
-          /*  executorService.submit(new Runnable() {
-                @Override
-                public void run() {*/
-                    //获取广告计划信息数据
-                    //reportService.getAdvertiserPlanReport(token, parse, parse, CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
-            reportService.getAdvertiserReport(token, parse, parse, CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
-
-                }
-           // });
-       // }
 
 
     }

+ 2 - 1
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IAccountWarningService.java

@@ -1,5 +1,6 @@
 package cn.com.ctop.kuaishou.modules.batch.service;
 
 public interface IAccountWarningService {
-    void accountWarning(Long account, String statDate, String anotherDay);
+    void kuaiShouAccountWarning(Long account, String statDate, String anotherDay);
+
 }

+ 12 - 4
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/AccountWarningServiceImpl.java

@@ -29,12 +29,12 @@ public class AccountWarningServiceImpl implements IAccountWarningService {
 
 
     /**
-     * 账户 出价预警
+     * 快手账户 出价预警
      *
      * @param accountId
      */
     @Override
-    public void accountWarning(Long accountId, String statDate, String anotherDay) {
+    public void kuaiShouAccountWarning(Long accountId, String statDate, String anotherDay) {
         try {
 
             Integer maxHour = hourlyAccountMapper.selectMaxHour(accountId, statDate);
@@ -105,7 +105,7 @@ public class AccountWarningServiceImpl implements IAccountWarningService {
         MailLog checkMailLog = mailLogMapper.selectOne(queryWrapper);
         if (Check.isNull(checkMailLog)) {
             List<String> mailList = mailLogMapper.selectMailList(projectId);
-            String subject = "较昨日同时段账户消耗预警";
+            String subject = "快手-较昨日同时段账户消耗预警";
             try {
                 SendMailUtil.sendMail(mailList, subject, text.toString());
                 MailLog mailLog = new MailLog();
@@ -146,7 +146,7 @@ public class AccountWarningServiceImpl implements IAccountWarningService {
         MailLog checkMailLog = mailLogMapper.selectOne(queryWrapper);
         if (Check.isNull(checkMailLog)) {
             List<String> mailList = mailLogMapper.selectMailList(projectId);
-            String subject = "账户消耗预警";
+            String subject = "快手-账户消耗预警";
             try {
                 SendMailUtil.sendMail(mailList, subject, text.toString());
                 MailLog mailLog = new MailLog();
@@ -167,4 +167,12 @@ public class AccountWarningServiceImpl implements IAccountWarningService {
     }
 
 
+
+
+
+
+
+
+
+
 }

+ 16 - 2
module-report/src/main/java/cn/com/ctop/bytedance/entity/BytedanceAdvertiserHourlyReport.java

@@ -5,12 +5,15 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import io.swagger.models.auth.In;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
+import org.jeecg.common.util.DateUtils;
 import org.jeecgframework.poi.excel.annotation.Excel;
 
 import java.math.BigDecimal;
+import java.text.ParseException;
 import java.util.Date;
 
 /**
@@ -45,6 +48,9 @@ public class BytedanceAdvertiserHourlyReport {
     @Excel(name = "数据起始时间", width = 15)
     @ApiModelProperty(value = "数据起始时间")
     private String statDatetime;
+
+
+    private Integer statHour;
     /**
      * 展示量
      */
@@ -417,7 +423,13 @@ public class BytedanceAdvertiserHourlyReport {
         }
         String statDatetime = data.getString("stat_datetime");
         if (null != statDatetime && !"".equals(statDatetime.trim())) {
-            this.statDatetime = statDatetime;
+
+            try {
+                this.statDatetime = DateUtils.getDateByDateStr(statDatetime);
+                this.statHour = DateUtils.getHour(statDatetime);
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
         }
         Long shopping = data.getLong("shopping");
         if (null != shopping) {
@@ -599,11 +611,13 @@ public class BytedanceAdvertiserHourlyReport {
         if (null != register) {
             this.register = register;
         }
-        this.id = "" + advertiserId + this.statDatetime.substring(0, 13).replace(" ", "");
+        this.id = "" + advertiserId + this.statDatetime + "_" + this.statHour;
         this.createTime = new Date();
         this.updateTime = new Date();
     }
 
     public BytedanceAdvertiserHourlyReport() {
     }
+
+
 }

+ 5 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/BytedanceAdvertiserHourlyReportMapper.java

@@ -2,6 +2,9 @@ package cn.com.ctop.bytedance.mapper;
 
 import cn.com.ctop.bytedance.entity.BytedanceAdvertiserHourlyReport;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
 
 /**
  * @Description: 广告主小时级别报表信息
@@ -10,5 +13,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @Version: V1.0
  */
 public interface BytedanceAdvertiserHourlyReportMapper extends BaseMapper<BytedanceAdvertiserHourlyReport> {
+    Integer selectMaxHour(@Param("accountId") Long accountId, @Param("statDate") String statDate);
 
+    BigDecimal getCost(@Param("accountId") Long accountId, @Param("statHour") Integer statHour, @Param("statDate") String statDate);
 }

+ 22 - 0
module-report/src/main/java/cn/com/ctop/bytedance/mapper/xml/BytedanceAdvertiserHourlyReportMapper.xml

@@ -2,4 +2,26 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="cn.com.ctop.bytedance.mapper.BytedanceAdvertiserHourlyReportMapper">
 
+
+    <select id="selectMaxHour" resultType="java.lang.Integer">
+        select max(stat_hour)
+        from
+        ctop_bytedance_report_advertiser_hourly
+        where advertiser_id = #{accountId}
+        and stat_datetime = #{statDate}
+
+    </select>
+
+    <select id="getCost" resultType="java.math.BigDecimal">
+        select cost
+        from
+        ctop_bytedance_report_advertiser_hourly
+        where
+        advertiser_id = #{accountId}
+        and stat_datetime = #{statDate}
+        and stat_hour = #{statHour}
+
+    </select>
+
+
 </mapper>

+ 5 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/IByteDanceHourlyAccountWarningService.java

@@ -0,0 +1,5 @@
+package cn.com.ctop.bytedance.service;
+
+public interface IByteDanceHourlyAccountWarningService {
+    void byteDanceAccountWarning(Long account, String statDate, String anotherDay);
+}

+ 174 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/ByteDanceHourlyAccountWarningServiceImpl.java

@@ -0,0 +1,174 @@
+package cn.com.ctop.bytedance.service.impl;
+
+import cn.com.ctop.bytedance.mapper.BytedanceAdvertiserHourlyReportMapper;
+import cn.com.ctop.bytedance.service.IByteDanceHourlyAccountWarningService;
+import cn.com.ctop.common.module.entity.MailLog;
+import cn.com.ctop.common.module.entity.UserAllocation;
+import cn.com.ctop.common.module.mapper.MailLogMapper;
+import cn.com.ctop.common.module.mapper.UserAllocationMapper;
+import cn.com.ctop.common.module.utils.BigDecimalUtil;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.CorpWexinUtils;
+import cn.com.ctop.common.module.utils.SendMailUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+@Service
+public class ByteDanceHourlyAccountWarningServiceImpl implements IByteDanceHourlyAccountWarningService {
+
+
+
+    @Autowired
+    private BytedanceAdvertiserHourlyReportMapper bytedanceAdvertiserHourlyReportMapper;
+    @Autowired
+    private UserAllocationMapper userAllocationMapper;
+    @Autowired
+    private MailLogMapper mailLogMapper;
+
+    /**
+     * 头条账户 出价预警
+     *
+     * @param accountId
+     */
+    @Override
+    public void byteDanceAccountWarning(Long accountId, String statDate, String anotherDay) {
+        try {
+
+            Integer maxHour = bytedanceAdvertiserHourlyReportMapper.selectMaxHour(accountId, statDate);
+            if (Check.isNull(maxHour)) {
+                return;
+            }
+            QueryWrapper<UserAllocation> userAllocationQueryWrapper = new QueryWrapper<>();
+            userAllocationQueryWrapper.eq("account_id", accountId);
+            userAllocationQueryWrapper.eq("media_id", 1);
+            userAllocationQueryWrapper.orderByDesc("create_time");
+            userAllocationQueryWrapper.last("limit 1");
+            UserAllocation userAllocation = userAllocationMapper.selectOne(userAllocationQueryWrapper);
+            if (Check.isNull(userAllocation)) {
+                return;
+            }
+            BigDecimal warningAmount = BigDecimalUtil.divideBigDecimal(userAllocation.getWarningAmount(),new BigDecimal(1000));
+            BigDecimal warningProportion = userAllocation.getWarningProportion();
+            BigDecimal nowCost = bytedanceAdvertiserHourlyReportMapper.getCost(accountId, maxHour, statDate);
+            if (maxHour != 0) {
+                if (!Check.isNull(nowCost) && nowCost.compareTo(new BigDecimal(0)) != 0) {
+                    BigDecimal lastHourCost = bytedanceAdvertiserHourlyReportMapper.getCost(accountId, maxHour - 1, statDate);
+                    if (!Check.isNull(lastHourCost) && lastHourCost.compareTo(new BigDecimal(0)) != 0) {
+                        if (!Check.isNull(userAllocation)) {
+                            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, nowCost, userAllocation.getProjectId(), userAllocation.getProjectName());
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (!Check.isNull(nowCost) && nowCost.compareTo(new BigDecimal(0)) != 0) {
+                BigDecimal yesterdayHourCost = bytedanceAdvertiserHourlyReportMapper.getCost(accountId, maxHour, anotherDay);
+                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, nowCost, userAllocation.getProjectId(), userAllocation.getProjectName());
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+    private void sendYesterdayMessage(Long accountId, String authName, Integer maxHour, BigDecimal nowCost, Long projectId, String projectName) {
+
+        StringBuilder text = new StringBuilder();
+        text.append("较昨日同时段消耗预警").append("<br/>")
+                .append("您的项目:" + projectName + "下的,").append("<br/>")
+                .append("账号:").append(accountId + ",").append("授权名称为:" + authName).append("<br/>")
+                .append("相较于昨日 " + maxHour + "时").append("<br/>")
+                .append("出现消耗暴涨,").append("消耗金额为:" + nowCost).append("<br/>")
+                .append("请您及时查看!");
+
+
+        QueryWrapper<MailLog> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id", accountId);
+        queryWrapper.eq("hour", maxHour);
+        queryWrapper.eq("mail_type", 3);
+        queryWrapper.orderByDesc("create_time");
+        queryWrapper.last("limit 1");
+        MailLog checkMailLog = mailLogMapper.selectOne(queryWrapper);
+        if (Check.isNull(checkMailLog)) {
+            List<String> mailList = mailLogMapper.selectMailList(projectId);
+            String subject = "头条-较昨日同时段账户消耗预警";
+            try {
+                SendMailUtil.sendMail(mailList, subject, text.toString());
+                MailLog mailLog = new MailLog();
+                mailLog.setAccountId(accountId);
+                mailLog.setMailType(3);
+                mailLog.setHour(maxHour);
+                mailLog.setContent(text.toString());
+                mailLog.setSendEmil(JSON.toJSONString(mailList));
+                mailLog.setSubject(subject);
+                mailLogMapper.insert(mailLog);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            List<String> wexinIds = mailLogMapper.selectWeiXinIdList(projectId);
+            CorpWexinUtils.sendMessage(wexinIds, text.toString());
+        }
+
+
+    }
+
+
+    private void sendMessage(Long accountId, String authName, Integer hour, BigDecimal amount, Long projectId, String projectName) {
+
+        StringBuilder text = new StringBuilder();
+        text.append("较上时段消耗预警").append("<br/>")
+                .append("您的项目:" + projectName + " 下的").append("<br/>")
+                .append("账号:").append(accountId + ",").append("授权名称为:" + authName).append("<br/>")
+                .append(hour + " 时").append("相较于 " + (hour - 1) + " 时").append("<br/>")
+                .append("出现消耗暴涨,").append("消耗金额为:" + amount).append("<br/>")
+                .append("请您及时查看!");
+
+        QueryWrapper<MailLog> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id", accountId);
+        queryWrapper.eq("hour", hour);
+        queryWrapper.eq("mail_type", 2);
+        queryWrapper.orderByDesc("create_time");
+        queryWrapper.last("limit 1");
+        MailLog checkMailLog = mailLogMapper.selectOne(queryWrapper);
+        if (Check.isNull(checkMailLog)) {
+            List<String> mailList = mailLogMapper.selectMailList(projectId);
+            String subject = "头条-账户消耗预警";
+            try {
+                SendMailUtil.sendMail(mailList, subject, text.toString());
+                MailLog mailLog = new MailLog();
+                mailLog.setAccountId(accountId);
+                mailLog.setMailType(2);
+                mailLog.setHour(hour);
+                mailLog.setContent(text.toString());
+                mailLog.setSendEmil(JSON.toJSONString(mailList));
+                mailLog.setSubject(subject);
+                mailLogMapper.insert(mailLog);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        List<String> wexinIds = mailLogMapper.selectWeiXinIdList(projectId);
+        CorpWexinUtils.sendMessage(wexinIds, text.toString());
+
+    }
+
+
+}

+ 1 - 0
module-report/src/main/java/cn/com/ctop/bytedance/service/impl/ReportServiceImpl.java

@@ -87,6 +87,7 @@ public class ReportServiceImpl implements IReportService {
         config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
         JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(conditions, config));
         JSONObject getObject = getAdvertiserStat(token, jsonObject);
+        System.err.println(getObject);
         Integer code = getObject.getInteger("code");
         String message = getObject.getString("message");
         if (null == code || code != 0) {