zhaoxian 1 anno fa
parent
commit
08b0faf0fc
93 ha cambiato i file con 11310 aggiunte e 609 eliminazioni
  1. 49 33
      kuaishou/pom.xml
  2. 8 6
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/KuaishouJobApplication.java
  3. 0 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/MybatisPlusConfig.java
  4. 0 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/XxlJobConfig.java
  5. 151 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/controller/BytedanceController.java
  6. 538 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/ByteDanceAdvertisePlan.java
  7. 198 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/ByteDanceAdvertiserReportDTO.java
  8. 622 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/BytedanceAdvertiserDailyReport.java
  9. 638 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/BytedanceAdvertiserHourlyReport.java
  10. 61 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/BytedanceAgentToken.java
  11. 167 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/CtopOauthToken.java
  12. 153 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/Project.java
  13. 59 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleAccountTemplate.java
  14. 75 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataAccount.java
  15. 41 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataCreative.java
  16. 95 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataPlan.java
  17. 78 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataTarget.java
  18. 33 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/TransactionDay.java
  19. 171 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/UserAllocation.java
  20. 75 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WarningOperationLog.java
  21. 63 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatAttendance.java
  22. 142 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatCheckinData.java
  23. 71 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatDepartment.java
  24. 66 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatNoList.java
  25. 65 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatUserList.java
  26. 86 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WexinConfig.java
  27. 166 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/enums/BytedanceConvertType.java
  28. 71 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/enums/DepartEnum.java
  29. 51 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AgentManagementJob.java
  30. 39 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AlarmRuleJob.java
  31. 52 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceHourlyAccountWarningLoadJob.java
  32. 45 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDancePlanRuleDataJob.java
  33. 38 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceRefreshTokenJob.java
  34. 60 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceAdvertiserDailyReportLoadJob.java
  35. 58 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceAdvertiserHourlyReportLoadJob.java
  36. 42 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedancePlanLoadJob.java
  37. 50 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceTodayPlaneLoadJob.java
  38. 26 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/CwjsPolicyApprovedNoticeJob.java
  39. 98 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuiXuanBytedanceJob.java
  40. 44 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuleDataAccountCleanJob.java
  41. 40 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/WechatApproveAttendanceJob.java
  42. 37 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/WechatAttendanceJob.java
  43. 22 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/AccountInfoMapper.java
  44. 16 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/CommonMapper.java
  45. 43 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/ReportDataMapper.java
  46. 21 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/SendMapper.java
  47. 25 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/TokenMapper.java
  48. 34 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/WechatMapper.java
  49. 56 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/AccountInfoMapper.xml
  50. 26 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/CommonMapper.xml
  51. 583 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/ReportDataMapper.xml
  52. 61 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/SendMapper.xml
  53. 90 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/TokenMapper.xml
  54. 240 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/WechatMapper.xml
  55. 15 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/AccountInfoService.java
  56. 12 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/CommonService.java
  57. 11 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/IMessageTemplate.java
  58. 18 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/ISendMessageService.java
  59. 23 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/ReportDataService.java
  60. 20 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/TokenService.java
  61. 19 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/WechatService.java
  62. 32 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/AccountInfoServiceImpl.java
  63. 88 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/CommonServiceImpl.java
  64. 36 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/MessageTemplateImpl.java
  65. 939 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/ReportDataServiceImpl.java
  66. 72 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/SendMessageServiceImpl.java
  67. 144 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/TokenServiceImpl.java
  68. 597 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/WechatServiceImpl.java
  69. 94 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/WexinServiceImpl.java
  70. 1 1
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/APIUtil.java
  71. 1 1
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/Check.java
  72. 1774 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/DateUtils.java
  73. 278 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/ExportExcelUtils.java
  74. 1 1
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/HttpGetWithBodyEntity.java
  75. 1 1
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/HttpUtil.java
  76. 1024 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/HttpUtils.java
  77. 1 1
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/KuaishouAPIConstant.java
  78. 38 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/QYWxConstant.java
  79. 1 1
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/Result.java
  80. 31 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/ResultMapUtils.java
  81. 61 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/SpNoEnum.java
  82. 124 0
      job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/StatusCode.java
  83. 12 15
      kuaishou/src/main/resources/application.yml
  84. 0 0
      job-bytedance/src/main/resources/log4j.properties
  85. 0 0
      job-bytedance/src/main/resources/logback-dev.xml
  86. 0 0
      job-bytedance/src/main/resources/logback-prod.xml
  87. 0 0
      job-bytedance/src/main/resources/logback-test.xml
  88. 0 0
      job-bytedance/src/test/java/cn/com/ctop/job/bytedance/SampleTest.java
  89. 0 27
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/controller/KuaishouController.java
  90. 0 382
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/DateUtils.java
  91. 0 137
      kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/HttpUtils.java
  92. 2 2
      pom.xml
  93. 1 1
      xxl-job-core/pom.xml

+ 49 - 33
kuaishou/pom.xml

@@ -4,7 +4,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>cn.com.ctop</groupId>
-    <artifactId>job-kuaishou</artifactId>
+    <artifactId>job-bytedance</artifactId>
     <version>1.0</version>
     <parent>
         <groupId>org.springframework.boot</groupId>
@@ -31,11 +31,11 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>com.github.xiaoymin</groupId>
-            <artifactId>swagger-bootstrap-ui</artifactId>
-            <version>1.9.3</version>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>com.github.xiaoymin</groupId>-->
+        <!--            <artifactId>swagger-bootstrap-ui</artifactId>-->
+        <!--            <version>1.9.3</version>-->
+        <!--        </dependency>-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
@@ -78,6 +78,22 @@
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>${mybatis-plus.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-cp</artifactId>
+            <version>3.6.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>fontbox</artifactId>
+            <version>2.0.15</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.17</version>
+        </dependency>
         <!-- druid -->
         <dependency>
             <groupId>com.alibaba</groupId>
@@ -91,12 +107,12 @@
             <version>2.5.4</version>
         </dependency>
         <!-- junit -->
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.12</version>
-            <scope>test</scope>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>junit</groupId>-->
+        <!--            <artifactId>junit</artifactId>-->
+        <!--            <version>4.12</version>-->
+        <!--            <scope>test</scope>-->
+        <!--        </dependency>-->
         <!-- json -->
         <dependency>
             <groupId>com.alibaba</groupId>
@@ -115,27 +131,27 @@
             <version>5.1.47</version>
             <scope>runtime</scope>
         </dependency>
-        <dependency>
-            <groupId>net.sourceforge.jtds</groupId>
-            <artifactId>jtds</artifactId>
-            <version>1.3.1</version>
-            <scope>runtime</scope>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>net.sourceforge.jtds</groupId>-->
+        <!--            <artifactId>jtds</artifactId>-->
+        <!--            <version>1.3.1</version>-->
+        <!--            <scope>runtime</scope>-->
+        <!--        </dependency>-->
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
             <artifactId>httpclient</artifactId>
             <version>4.5.9</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpcore</artifactId>
-            <version>4.4</version>
-        </dependency>
-        <dependency>
-            <groupId>com.squareup.retrofit2</groupId>
-            <artifactId>retrofit</artifactId>
-            <version>2.6.0</version>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>org.apache.httpcomponents</groupId>-->
+        <!--            <artifactId>httpcore</artifactId>-->
+        <!--            <version>4.4</version>-->
+        <!--        </dependency>-->
+        <!--        <dependency>-->
+        <!--            <groupId>com.squareup.retrofit2</groupId>-->
+        <!--            <artifactId>retrofit</artifactId>-->
+        <!--            <version>2.6.0</version>-->
+        <!--        </dependency>-->
         <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
@@ -145,11 +161,11 @@
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
         </dependency>
-        <dependency>
-            <groupId>cn.hutool</groupId>
-            <artifactId>hutool-all</artifactId>
-            <version>4.5.11</version>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>cn.hutool</groupId>-->
+        <!--            <artifactId>hutool-all</artifactId>-->
+        <!--            <version>4.5.11</version>-->
+        <!--        </dependency>-->
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>

+ 8 - 6
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/KuaishouJobApplication.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou;
+package cn.com.ctop.job.bytedance;
 
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.SpringApplication;
@@ -9,14 +9,16 @@ import org.springframework.context.annotation.Configuration;
 @SpringBootApplication
 @ComponentScan(basePackages = {"cn.com.ctop"})
 @Configuration
-public class KuaishouJobApplication {
+public class BytedanceJobApplication {
     public static void main(String[] args){
 
-        SpringApplication.run(KuaishouJobApplication.class, args);
+        SpringApplication.run(BytedanceJobApplication.class, args);
 
-        log.info("\n----------------------------------------------------------\n\t" +
-                "job service is running\n\t" +
-                "----------------------------------------------------------");
+        log.info("\n\t----------------------------------------------------------\n\t" +
+                "\t\t\t\tjob service is running\n\t" +
+                "----------------------------------------------------------\n\t" +
+                "Local_Url: \thttp://localhost:8087/bytedanceController\n\t"
+        );
     }
 
 }

kuaishou/src/main/java/cn/com/ctop/job/kuaishou/config/MybatisPlusConfig.java → job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/MybatisPlusConfig.java


kuaishou/src/main/java/cn/com/ctop/job/kuaishou/config/XxlJobConfig.java → job-bytedance/src/main/java/cn/com/ctop/job/bytedance/config/XxlJobConfig.java


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

@@ -0,0 +1,151 @@
+package cn.com.ctop.job.controller;
+
+import cn.com.ctop.job.bytedance.entity.WechatAttendance;
+import cn.com.ctop.job.bytedance.service.WechatService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import cn.com.ctop.job.bytedance.utils.ExportExcelUtils;
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@RestController
+@RequestMapping("/bytedanceController")
+@Slf4j
+public class BytedanceController {
+
+    @Autowired
+
+    private WechatService wechatService;
+
+
+    @GetMapping(value = "/test")
+    public String test(Long accountId) {
+        System.out.println("ok");
+        return "ok";
+    }
+
+
+    //更新人员和部门
+    @GetMapping("getUser")
+    public String getUser() {
+        long startTime = System.currentTimeMillis();
+        wechatService.getUserList();
+        String txt = "执行更新人员和部门完成,用时:" + (System.currentTimeMillis() - startTime) / 1000 + " s ";
+        System.out.println(txt);
+        return txt;
+    }
+
+
+    //日常考勤数据
+    @GetMapping("getCheckinData")
+    public String getCheckinData(String start, String end) {
+        if (Check.isNull(start) || Check.isNull(end)) {
+            return "时间参数不能为空";
+        }
+        String txt = null;
+        try {
+            Long startTime = System.currentTimeMillis();
+            wechatService.getCheckinData(start + " 00:00:00", end + " 23:59:59");
+            Thread.sleep(5000L);
+            wechatService.getNoListDate(start + " 00:00:00", end + " 23:59:59", "0");
+
+            txt = "考勤执行完成,用时:" + (System.currentTimeMillis() - startTime) / 1000 + " s ";
+            System.out.println(txt);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        return txt;
+    }
+
+
+    //异常考勤数据
+    @GetMapping("getNoList")
+    public String getNoList(String start, String end) {
+        long startTime = System.currentTimeMillis();
+        wechatService.getNoListDate(start + " 00:00:00", end + " 23:59:59", "0");
+        String txt = "异常考勤执行完成,用时:" + (System.currentTimeMillis() - startTime) / 1000 + " s ";
+        return txt;
+    }
+
+
+    /**
+     * 考勤记录 导出数据
+     */
+    @GetMapping("/exportData")
+    public void getExcelReport(HttpServletResponse response, String start, String end, String departName, Long departId, String userName, String userId) {
+        if (Check.isNull(start) || Check.isNull(end)) {
+            return;
+        }
+        Map<String, Object> paramsMap = new HashMap<>();
+        paramsMap.put("startTime", start + " 00:00:00");
+        paramsMap.put("stopTime", end + " 23:59:59");
+        paramsMap.put("departName", departName);
+        paramsMap.put("departId", departId);
+        paramsMap.put("userName", userName);
+        paramsMap.put("userId", userId);
+        List<WechatAttendance> excelData = wechatService.queryAttendanceData(paramsMap);
+        List<WechatAttendance> overtimeData = wechatService.queryOverTimeData(paramsMap);
+        try {
+            List<List<Object>> excelList = new ArrayList<>();
+            List<List<Object>> excelYRList = new ArrayList<>();
+            List<List<Object>> overtimeExcelList = new ArrayList<>();
+            List<List<Object>> overtimeYRExcelList = new ArrayList<>();
+            if (!excelData.isEmpty()) {
+                excelData.forEach(data -> {
+                    List<Object> temp = new ArrayList<>();
+                    temp.add(data.getUserName());
+                    temp.add(data.getDepartName());
+                    temp.add(data.getCheckinDate());
+                    temp.add(data.getCheckinType());
+                    temp.add(data.getExceptionType());
+                    temp.add(data.getCheckinTime());
+                    temp.add(data.getType());
+                    temp.add(data.getStateDuration());
+                    if (!Check.isNull(data.getStatus())) {
+                        temp.add("1".equals(data.getStatus()) ? "审批中" : "已通过");
+                    } else {
+                        temp.add("");
+                    }
+                    excelList.add(temp);
+                });
+            }
+            if (!overtimeData.isEmpty()) {
+                overtimeData.forEach(data -> {
+                    List<Object> temp = new ArrayList<>();
+                    temp.add(data.getUserName());
+                    temp.add(data.getDepartName());
+                    temp.add(data.getCheckinDate());
+                    temp.add(data.getOvertime());
+                    overtimeExcelList.add(temp);
+                });
+            }
+            OutputStream os = response.getOutputStream();
+            ExportExcelUtils eeu = new ExportExcelUtils();
+            XSSFWorkbook workbook = new XSSFWorkbook();
+            String[] titles = {"姓名", "部门", "考勤日期", "考勤类型", "考勤状态", "考勤时间", "审核状态", "状态时长", "审批状态"};
+            String[] overtimeTitles = {"姓名", "部门", "加班日期", "加班时长"};
+            eeu.exportExcelForAttendance(workbook, 0, "汇创异常考勤", titles, excelList);
+            eeu.exportExcel(workbook, 1, "汇创加班考勤", overtimeTitles, overtimeExcelList);
+            HttpUtils.setResponseHeader(response, start + "~" + end + " clockIn.xlsx");
+            workbook.write(os);
+            os.flush();
+            os.close();
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        }
+    }
+
+}

+ 538 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/ByteDanceAdvertisePlan.java

@@ -0,0 +1,538 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import cn.com.ctop.job.bytedance.utils.Check;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 今日头条广告计划信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-07-22
+ */
+@Data
+@TableName("ctop_bytedance_advertise_plan")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_advertise_plan对象", description = "今日头条广告计划信息")
+public class ByteDanceAdvertisePlan {
+    @TableId
+    private Long id;
+
+    private String accountId;
+
+    // 计划名称
+    private String name;
+
+    @TableField(exist = false)
+    private Object names;
+
+    @TableField(exist = false)
+    private String landingType;
+
+    private Long campaignId;
+
+    private String operation;
+
+    private String unionVideoType;
+
+    // 上次修改时间戳(用于更新时提交,服务端判断是否基于最新信息修改)
+    private String planModifyTime;
+
+    // 投放范围
+    private String deliveryRange;
+
+    // 计划上次修改时间
+    private String adModifyTime;
+
+    // 计划创建时间
+    private String adCreateTime;
+
+    // 广告预算类型
+    private String budgetMode;
+
+    // 广告预算
+    private BigDecimal budget;
+
+    // 广告计划投放状态
+    private String toutiaoStatus;
+
+    //true:投放中 false:暂停
+    private Boolean planStatus;
+
+    // 广告计划操作状态
+    private String optStatus;
+
+    // 广告投放起始时间
+    private String startTime;
+
+    // 广告投放结束时间
+    private String endTime;
+
+    // 广告出价
+    private BigDecimal bid;
+
+    // 广告出价类型
+    private String pricing;
+
+    // 广告投放时间类型
+    private String scheduleType;
+
+    // 广告投放时段
+    private String scheduleTime;
+
+    // 广告投放速度类型
+    private String flowControlMode;
+
+    // 应用直达链接
+    private String openUrl;
+
+    // 应用下载方式
+    private String downloadType;
+
+    // 应用下载方式
+    private String downloadUrl;
+
+    // 广告落地页链接
+    private String externalUrl;
+
+    // 广告应用下载包名
+    private String toutiaoPackage;
+
+    // 广告应用下载类型
+    private String appType;
+
+    // 广告计划审核不通过原因
+    private String auditRejectReason;
+
+    // ocpc广告转化出价
+    private BigDecimal cpaBid;
+
+    // 深度优化出价
+    private BigDecimal deepCpaBid;
+
+    private String deepBidType;
+
+    private Integer cpaSkipFirstPhrase;
+
+    // 转化类型广告的转化工具id
+    private Long convertId;
+
+    // 过滤已转化用户类型字段
+    private String hideIfConverted;
+
+    // 过滤已安装,当推广目标为安卓应用下载时可填
+    private Integer hideIfExists;
+
+    private String convertedTimeDuration;
+
+
+    // audience
+    private String audience;
+
+    private String modifyTime;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    private BigDecimal lubanRoiGoal;
+
+    private BigDecimal roiGoal;
+    /**
+     * 受众公共参数
+     */
+    // 受众性别
+    private String gender;
+    // 受众平台
+    @TableField(exist = false)
+    private Object platform;
+    @TableField(exist = false)
+    private Object retargetingTags;
+    @TableField(exist = false)
+    private Object retargetingTagsExclude;
+    @TableField(exist = false)
+    private Object age;
+    @TableField(exist = false)
+    private Object carrier;
+    @TableField(exist = false)
+    private Object ac;
+    @TableField(exist = false)
+    private Object deviceBrand;
+    @TableField(exist = false)
+    private Object articleCategory;
+    @TableField(exist = false)
+    private Object activateType;
+    @TableField(exist = false)
+    private Object city;
+    @TableField(exist = false)
+    private Object businessIds;
+    @TableField(exist = false)
+    private String locationType;
+    @TableField(exist = false)
+    private Object superiorPopularityType;
+    @TableField(exist = false)
+    private Object flowPackage;
+    @TableField(exist = false)
+    private Object excludeFlowPackage;
+    @TableField(exist = false)
+    private Object deviceType;
+    @TableField(exist = false)
+    private Object autoExtendEnabled;
+    @TableField(exist = false)
+    private Object launchPrice;
+    @TableField(exist = false)
+    private Object interestActionMode;
+    @TableField(exist = false)
+    private Object actionScene;
+    @TableField(exist = false)
+    private Object actionDays;
+    @TableField(exist = false)
+    private Object actionCategories;
+    @TableField(exist = false)
+    private Object actionWords;
+    @TableField(exist = false)
+    private Object interestCategories;
+    @TableField(exist = false)
+    private Object interestWords;
+    @TableField(exist = false)
+    private Object geolocation;
+    @TableField(exist = false)
+    private String externalAction;
+    @TableField(exist = false)
+    private String useOpenUrl;
+
+
+    //点击监测链接
+    private String actionTrackUrl;
+
+
+    public ByteDanceAdvertisePlan(JSONObject dataObject, String accountId) {
+        this.id = dataObject.getLong("id");
+        this.accountId = accountId;
+        String name = dataObject.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+        JSONObject audience = dataObject.getJSONObject("audience");
+        if (null != audience) {
+            this.audience = audience.toJSONString();
+            JSONArray platform = audience.getJSONArray("platform");
+            if (null != platform && platform.size() > 0) {
+                String plat = "";
+                for (int i = 0; i < platform.size(); i++) {
+                    String platformStr = platform.getString(i);
+                    if ("IOS".equals(platformStr)) {
+                        plat += "ios,";
+                    } else {
+                        plat += "安卓,";
+                    }
+                }
+                this.platform = plat.substring(0, plat.length() - 1);
+            }
+            String gender = audience.getString("gender");
+            if (null != gender) {
+                if ("NONE".equals(gender)) {
+                    this.gender = "不限";
+                } else if ("GENDER_MALE".equals(gender)) {
+                    this.gender = "男";
+                } else {
+                    this.gender = "女";
+                }
+            }
+        }
+        this.createTime = new Date();
+        this.updateTime = new Date();
+        Long advertiserId = dataObject.getLong("advertiser_id");
+
+        if (null != advertiserId) {
+            this.accountId = advertiserId + "";
+        }
+        Long campaignId = dataObject.getLong("campaign_id");
+        if (null != campaignId) {
+            this.campaignId = campaignId;
+        }
+
+        String budgetMode = dataObject.getString("budget_mode");
+        if (null != budgetMode && !"".equals(budgetMode.trim())) {
+            this.budgetMode = budgetMode;
+        }
+        String modifyTime = dataObject.getString("modify_time");
+        if (null != modifyTime && !"".equals(modifyTime.trim())) {
+            this.modifyTime = modifyTime;
+        }
+        String openUrl = dataObject.getString("open_url");
+        if (null != openUrl && !"".equals(openUrl.trim())) {
+            this.openUrl = openUrl;
+        }
+
+        String adCreateTime = dataObject.getString("ad_create_time");
+        if (null != adCreateTime && !"".equals(adCreateTime.trim())) {
+            this.adCreateTime = adCreateTime;
+        }
+
+        String adModifyTime = dataObject.getString("ad_modify_time");
+        if (null != adModifyTime && !"".equals(adModifyTime.trim())) {
+            this.adModifyTime = adModifyTime;
+        }
+
+        String auditRejectReason = dataObject.getString("audit_reject_reason");
+        if (null != auditRejectReason && !"".equals(auditRejectReason.trim())) {
+            this.auditRejectReason = auditRejectReason;
+        }
+
+        String pricing = dataObject.getString("pricing");
+        if (null != pricing && !"".equals(pricing.trim())) {
+            this.pricing = pricing;
+        }
+
+
+        Integer hideIfExists = dataObject.getInteger("hide_if_exists");
+        if (null != hideIfExists) {
+            this.hideIfExists = hideIfExists;
+        }
+
+        String appType = dataObject.getString("app_type");
+        if (null != appType && !"".equals(appType.trim())) {
+            this.appType = appType;
+        }
+
+        String flowControlMode = dataObject.getString("flow_control_mode");
+        if (null != flowControlMode && !"".equals(flowControlMode.trim())) {
+            this.flowControlMode = flowControlMode;
+        }
+
+
+        BigDecimal cpaBid = dataObject.getBigDecimal("cpa_bid");
+        if (null != cpaBid) {
+            this.cpaBid = cpaBid;
+        }
+
+        String startTime = dataObject.getString("start_time");
+        if (null != startTime && !"".equals(startTime.trim())) {
+            this.startTime = startTime;
+        }
+
+        String optStatus = dataObject.getString("opt_status");
+        if (null != optStatus && !"".equals(optStatus.trim())) {
+            this.optStatus = optStatus;
+        }
+
+        String endTime = dataObject.getString("end_time");
+        if (null != endTime && !"".equals(endTime.trim())) {
+            this.endTime = endTime;
+        }
+
+        String status = dataObject.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.toutiaoStatus = status;
+        }
+
+        Long convertId = dataObject.getLong("convert_id");
+        if (null != convertId) {
+            this.convertId = convertId;
+        }
+
+        BigDecimal bid = dataObject.getBigDecimal("bid");
+        if (null != bid) {
+            this.bid = bid;
+        }
+
+        String hideIfConverted = dataObject.getString("hide_if_converted");
+        if (null != hideIfConverted && !"".equals(hideIfConverted.trim())) {
+            this.hideIfConverted = hideIfConverted;
+        }
+
+        String toutiaoPackage = dataObject.getString("package");
+        if (null != toutiaoPackage && !"".equals(toutiaoPackage.trim())) {
+            this.toutiaoPackage = toutiaoPackage;
+        }
+
+        String deliveryRange = dataObject.getString("delivery_range");
+        if (null != deliveryRange && !"".equals(deliveryRange.trim())) {
+            this.deliveryRange = deliveryRange;
+        }
+
+        BigDecimal budget = dataObject.getBigDecimal("budget");
+        if (null != budget) {
+            this.budget = budget;
+        }
+
+        String scheduleType = dataObject.getString("schedule_type");
+        if (null != scheduleType && !"".equals(scheduleType.trim())) {
+            this.scheduleType = scheduleType;
+        }
+
+        String scheduleTime = dataObject.getString("schedule_time");
+        if (null != scheduleTime && !"".equals(scheduleTime.trim())) {
+            this.scheduleTime = scheduleTime;
+        }
+
+        String downloadType = dataObject.getString("download_type");
+        if (null != downloadType && !"".equals(downloadType.trim())) {
+            this.downloadType = downloadType;
+        }
+
+        String downloadUrl = dataObject.getString("download_url");
+        if (null != downloadUrl && !"".equals(downloadUrl.trim())) {
+            this.downloadUrl = downloadUrl;
+        }
+
+        String externalUrl = dataObject.getString("external_url");
+        if (null != externalUrl && !"".equals(externalUrl.trim())) {
+            this.externalUrl = externalUrl;
+        }
+        JSONArray action_track_url = dataObject.getJSONArray("action_track_url");
+        if (!Check.isNull(action_track_url)) {
+            this.actionTrackUrl = action_track_url.getString(0);
+        }
+    }
+
+    public ByteDanceAdvertisePlan(String advertiserId, Long adId, JSONObject params) {
+        this.id = adId;
+        this.accountId = advertiserId;
+        String name = params.getString("name");
+        if (null != name && !"".equals(name.trim())) {
+            this.name = name;
+        }
+
+        Long campaignId = params.getLong("campaign_id");
+        if (null != campaignId) {
+            this.campaignId = campaignId;
+        }
+
+        String budgetMode = params.getString("budget_mode");
+        if (null != budgetMode && !"".equals(budgetMode.trim())) {
+            this.budgetMode = budgetMode;
+        }
+
+        String openUrl = params.getString("open_url");
+        if (null != openUrl && !"".equals(openUrl.trim())) {
+            this.openUrl = openUrl;
+        }
+
+        String adCreateTime = params.getString("ad_create_time");
+        if (null != adCreateTime && !"".equals(adCreateTime.trim())) {
+            this.adCreateTime = adCreateTime;
+        }
+
+        String adModifyTime = params.getString("ad_modify_time");
+        if (null != adModifyTime && !"".equals(adModifyTime.trim())) {
+            this.adModifyTime = adModifyTime;
+        }
+
+        String auditRejectReason = params.getString("audit_reject_reason");
+        if (null != auditRejectReason && !"".equals(auditRejectReason.trim())) {
+            this.auditRejectReason = auditRejectReason;
+        }
+
+        String pricing = params.getString("pricing");
+        if (null != pricing && !"".equals(pricing.trim())) {
+            this.pricing = pricing;
+        }
+
+        Integer hideIfExists = params.getInteger("hide_if_exists");
+        if (null != hideIfExists) {
+            this.hideIfExists = hideIfExists;
+        }
+
+        String appType = params.getString("app_type");
+        if (null != appType && !"".equals(appType.trim())) {
+            this.appType = appType;
+        }
+
+        String flowControlMode = params.getString("flow_control_mode");
+        if (null != flowControlMode && !"".equals(flowControlMode.trim())) {
+            this.flowControlMode = flowControlMode;
+        }
+
+        BigDecimal cpaBid = params.getBigDecimal("cpa_bid");
+        if (null != cpaBid) {
+            this.cpaBid = cpaBid;
+        }
+
+        String startTime = params.getString("start_time");
+        if (null != startTime && !"".equals(startTime.trim())) {
+            this.startTime = startTime;
+        }
+
+        String optStatus = params.getString("opt_status");
+        if (null != optStatus && !"".equals(optStatus.trim())) {
+            this.optStatus = optStatus;
+        }
+
+        String endTime = params.getString("end_time");
+        if (null != endTime && !"".equals(endTime.trim())) {
+            this.endTime = endTime;
+        }
+
+        String status = params.getString("status");
+        if (null != status && !"".equals(status.trim())) {
+            this.toutiaoStatus = status;
+        }
+
+        Long convertId = params.getLong("convert_id");
+        if (null != convertId) {
+            this.convertId = convertId;
+        }
+
+        BigDecimal bid = params.getBigDecimal("bid");
+        if (null != bid) {
+            this.bid = bid;
+        }
+
+        String hideIfConverted = params.getString("hide_if_converted");
+        if (null != hideIfConverted && !"".equals(hideIfConverted.trim())) {
+            this.hideIfConverted = hideIfConverted;
+        }
+
+        String toutiaoPackage = params.getString("package");
+        if (null != toutiaoPackage && !"".equals(toutiaoPackage.trim())) {
+            this.toutiaoPackage = toutiaoPackage;
+        }
+
+        String deliveryRange = params.getString("delivery_range");
+        if (null != deliveryRange && !"".equals(deliveryRange.trim())) {
+            this.deliveryRange = deliveryRange;
+        }
+
+        BigDecimal budget = params.getBigDecimal("budget");
+        if (null != budget) {
+            this.budget = budget;
+        }
+
+        String scheduleType = params.getString("schedule_type");
+        if (null != scheduleType && !"".equals(scheduleType.trim())) {
+            this.scheduleType = scheduleType;
+        }
+
+        String scheduleTime = params.getString("schedule_time");
+        if (null != scheduleTime && !"".equals(scheduleTime.trim())) {
+            this.scheduleTime = scheduleTime;
+        }
+
+        String downloadType = params.getString("download_type");
+        if (null != downloadType && !"".equals(downloadType.trim())) {
+            this.downloadType = downloadType;
+        }
+
+        String externalUrl = params.getString("external_url");
+        if (null != externalUrl && !"".equals(externalUrl.trim())) {
+            this.externalUrl = externalUrl;
+        }
+    }
+
+    public ByteDanceAdvertisePlan() {
+    }
+}

+ 198 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/ByteDanceAdvertiserReportDTO.java

@@ -0,0 +1,198 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class ByteDanceAdvertiserReportDTO implements Serializable {
+    private Long advertiserId;
+    private String startDate;
+    private String endDate;
+    private Integer pageSize;
+    private Integer page;
+    private String timeGranularity;
+
+
+
+    private List<String> fields;
+
+
+
+    public List<String> getFieldsList(){
+        List<String> fields = new ArrayList<>();
+        fields.add("cost");
+        fields.add("show");
+        fields.add("avg_show_cost");
+        fields.add("avg_click_cost");
+        fields.add("click");
+        fields.add("ctr");
+        fields.add("convert");
+        fields.add("convert_cost");
+        fields.add("convert_rate");
+        fields.add("deep_convert");
+        fields.add("deep_convert_cost");
+        fields.add("deep_convert_rate");
+        fields.add("attribution_convert");
+        fields.add("attribution_convert_cost");
+        fields.add("attribution_deep_convert");
+        fields.add("attribution_deep_convert_cost");
+        fields.add("download_start");
+        fields.add("download_start_cost");
+        fields.add("download_start_rate");
+        fields.add("download_finish");
+        fields.add("download_finish_cost");
+        fields.add("download_finish_rate");
+        fields.add("install_finish");
+        fields.add("install_finish_cost");
+        fields.add("install_finish_rate");
+        fields.add("active");
+        fields.add("active_cost");
+        fields.add("active_rate");
+        fields.add("register");
+        fields.add("active_register_cost");
+        fields.add("active_register_rate");
+        fields.add("attribution_next_day_open_cnt");
+        fields.add("attribution_next_day_open_cost");
+        fields.add("attribution_next_day_open_rate");
+        fields.add("next_day_open");
+        fields.add("game_addiction");
+        fields.add("game_addiction_cost");
+        fields.add("game_addiction_rate");
+        fields.add("pay_count");
+        fields.add("active_pay_cost");
+        fields.add("active_pay_rate");
+        fields.add("game_pay_count");
+        fields.add("game_pay_cost");
+        fields.add("attribution_game_pay_7d_count");
+        fields.add("attribution_game_pay_7d_cost");
+        fields.add("attribution_active_pay_7d_per_count");
+        fields.add("loan_completion");
+        fields.add("loan_completion_cost");
+        fields.add("loan_completion_rate");
+        fields.add("pre_loan_credit");
+        fields.add("pre_loan_credit_cost");
+        fields.add("loan_credit");
+        fields.add("loan_credit_cost");
+        fields.add("loan_credit_rate");
+        fields.add("in_app_uv");
+        fields.add("in_app_detail_uv");
+        fields.add("in_app_cart");
+        fields.add("in_app_pay");
+        fields.add("in_app_order");
+        fields.add("phone");
+        fields.add("form");
+        fields.add("map_search");
+        fields.add("button");
+        fields.add("view");
+        fields.add("download");
+        fields.add("qq");
+        fields.add("lottery");
+        fields.add("vote");
+        fields.add("message");
+        fields.add("redirect");
+        fields.add("shopping");
+        fields.add("consult");
+        fields.add("wechat");
+        fields.add("wechat_login_count");
+        fields.add("attribution_wechat_login_30d_count");
+        fields.add("wechat_login_cost");
+        fields.add("attribution_wechat_login_30d_cost");
+        fields.add("wechat_first_pay_count");
+        fields.add("attribution_wechat_first_pay_30d_count");
+        fields.add("wechat_first_pay_cost");
+        fields.add("attribution_wechat_first_pay_30d_cost");
+        fields.add("wechat_first_pay_rate");
+        fields.add("attribution_wechat_first_pay_30d_rate");
+        fields.add("wechat_pay_amount");
+        fields.add("attribution_wechat_pay_30d_amount");
+        fields.add("attribution_wechat_pay_30d_roi");
+        fields.add("phone_connect");
+        fields.add("phone_confirm");
+        fields.add("phone_effective");
+        fields.add("consult_effective");
+        fields.add("coupon");
+        fields.add("coupon_single_page");
+        fields.add("redirect_to_shop");
+        fields.add("poi_address_click");
+        fields.add("poi_collect");
+        fields.add("luban_order_cnt");
+        fields.add("luban_order_stat_amount");
+        fields.add("luban_order_roi");
+        fields.add("luban_live_enter_cnt");
+        fields.add("live_watch_one_minute_count");
+        fields.add("luban_live_follow_cnt");
+        fields.add("live_fans_club_join_cnt");
+        fields.add("luban_live_comment_cnt");
+        fields.add("luban_live_share_cnt");
+        fields.add("luban_live_gift_cnt");
+        fields.add("luban_live_gift_amount");
+        fields.add("luban_live_slidecart_click_cnt");
+        fields.add("luban_live_click_product_cnt");
+        fields.add("luban_live_pay_order_count");
+        fields.add("luban_live_pay_order_stat_cost");
+        //fields.add("live_pay_order_cost_per_order");
+        fields.add("total_play");
+        fields.add("valid_play");
+        fields.add("valid_play_cost");
+        fields.add("valid_play_rate");
+        fields.add("play_25_feed_break");
+        fields.add("play_50_feed_break");
+        fields.add("play_100_feed_break");
+        //fields.add("play_25_feed_break_rate");
+        //fields.add("play_50_feed_break_rate");
+        //fields.add("play_100_feed_break_rate");
+        //fields.add("play_75_feed_break_rate");
+        fields.add("average_play_time_per_play");
+        //fields.add("play_over");
+        fields.add("play_over_rate");
+        fields.add("wifi_play_rate");
+        fields.add("wifi_play");
+        fields.add("card_show");
+        //fields.add("play_duration_2s_rate");
+        //fields.add("play_duration_3s_rate");
+        //fields.add("play_duration_5s_rate");
+        //fields.add("play_duration_10s_rate");
+        fields.add("advanced_creative_phone_click");
+        fields.add("advanced_creative_counsel_click");
+        fields.add("advanced_creative_form_click");
+        fields.add("advanced_creative_coupon_addition");
+        fields.add("advanced_creative_form_submit");
+        fields.add("share");
+        fields.add("comment");
+        fields.add("like");
+        fields.add("follow");
+        //fields.add("dislike");
+        //fields.add("report");
+        fields.add("message_action");
+        fields.add("home_visited");
+        fields.add("ies_challenge_click");
+        fields.add("ies_music_click");
+        fields.add("location_click");
+        fields.add("click_download");
+        fields.add("click_call_dy");
+        fields.add("click_shopwindow");
+        fields.add("click_website");
+        fields.add("click_landing_page");
+        //fields.add("interact_per_cost");
+        //fields.add("convert_show_rate");
+        //fields.add("cpc");
+        //fields.add("cpm");
+        //fields.add("cpa");
+        fields.add("submit_certification_count");
+        fields.add("approval_count");
+        fields.add("first_order_count");
+        fields.add("first_rental_order_count");
+        fields.add("commute_first_pay_count");
+        fields.add("live_component_click_count");
+        fields.add("live_component_click_cost");
+        fields.add("live_component_click_rate");
+        return fields;
+
+    }
+
+
+
+}

+ 622 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/BytedanceAdvertiserDailyReport.java

@@ -0,0 +1,622 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+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 java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 广告主日报表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-09-10
+ */
+@Data
+@TableName("ctop_bytedance_report_advertiser_daily")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_report_advertiser_daily对象", description = "广告主日报表")
+public class BytedanceAdvertiserDailyReport {
+
+    /**
+     * id
+     */
+    @TableId()
+    @ApiModelProperty(value = "id")
+    private String id;
+    /**
+     * 广告主id
+     */
+    @Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private Long advertiserId;
+    /**
+     * 数据起始时间
+     */
+    @Excel(name = "数据起始时间", width = 15)
+    @ApiModelProperty(value = "数据起始时间")
+    private String statDatetime;
+    /**
+     * 展示量
+     */
+    @Excel(name = "展示量", width = 15)
+    @ApiModelProperty(value = "展示量")
+    private Long showNum;
+    /**
+     * 点击量
+     */
+    @Excel(name = "点击量", width = 15)
+    @ApiModelProperty(value = "点击量")
+    private Long click;
+    /**
+     * 转化量
+     */
+    @Excel(name = "转化量", width = 15)
+    @ApiModelProperty(value = "转化量")
+    private Long convertNum;
+    /**
+     * 总花费
+     */
+    @Excel(name = "总花费", width = 15)
+    @ApiModelProperty(value = "总花费")
+    private BigDecimal cost;
+    /**
+     * 应用下载-激活
+     */
+    @Excel(name = "应用下载-激活", width = 15)
+    @ApiModelProperty(value = "应用下载-激活")
+    private Long active;
+    /**
+     * 应用下载-安卓下载完成
+     */
+    @Excel(name = "应用下载-安卓下载完成", width = 15)
+    @ApiModelProperty(value = "应用下载-安卓下载完成")
+    private Long downloadFinish;
+    /**
+     * 应用下载-安卓下载开始
+     */
+    @Excel(name = "应用下载-安卓下载开始", width = 15)
+    @ApiModelProperty(value = "应用下载-安卓下载开始")
+    private Long downloadStart;
+    /**
+     * 应用下载-点击安装数
+     */
+    @Excel(name = "应用下载-点击安装数", width = 15)
+    @ApiModelProperty(value = "应用下载-点击安装数")
+    private Long clickInstall;
+    /**
+     * 应用下载-安卓安装完成
+     */
+    @Excel(name = "应用下载-安卓安装完成", width = 15)
+    @ApiModelProperty(value = "应用下载-安卓安装完成")
+    private Long installFinish;
+    /**
+     * 应用下载-注册
+     */
+    @Excel(name = "应用下载-注册", width = 15)
+    @ApiModelProperty(value = "应用下载-注册")
+    private Long register;
+    /**
+     * 应用下载-付费数
+     */
+    @Excel(name = "应用下载-付费数", width = 15)
+    @ApiModelProperty(value = "应用下载-付费数")
+    private Long payCount;
+    /**
+     * 应用下载-到达uv
+     */
+    @Excel(name = "应用下载-到达uv", width = 15)
+    @ApiModelProperty(value = "应用下载-到达uv")
+    private Long inAppUv;
+    /**
+     * 应用下载-详情页到站uv
+     */
+    @Excel(name = "应用下载-详情页到站uv", width = 15)
+    @ApiModelProperty(value = "应用下载-详情页到站uv")
+    private Long inAppDetailUv;
+    /**
+     * 应用下载-加入购物车
+     */
+    @Excel(name = "应用下载-加入购物车", width = 15)
+    @ApiModelProperty(value = "应用下载-加入购物车")
+    private Long inAppCart;
+    /**
+     * 应用下载-提交订单
+     */
+    @Excel(name = "应用下载-提交订单", width = 15)
+    @ApiModelProperty(value = "应用下载-提交订单")
+    private Long inAppOrder;
+    /**
+     * 应用下载-付费
+     */
+    @Excel(name = "应用下载-付费", width = 15)
+    @ApiModelProperty(value = "应用下载-付费")
+    private Long inAppPay;
+    /**
+     * 落地页-电话拨打数
+     */
+    @Excel(name = "落地页-电话拨打数", width = 15)
+    @ApiModelProperty(value = "落地页-电话拨打数")
+    private Long phone;
+    /**
+     * 表单提交数
+     */
+    @Excel(name = "表单提交数", width = 15)
+    @ApiModelProperty(value = "表单提交数")
+    private Long form;
+    /**
+     * 落地页-地图搜索
+     */
+    @Excel(name = "落地页-地图搜索", width = 15)
+    @ApiModelProperty(value = "落地页-地图搜索")
+    private Long mapSearch;
+    /**
+     * 落地页-按钮button
+     */
+    @Excel(name = "落地页-按钮button", width = 15)
+    @ApiModelProperty(value = "落地页-按钮button")
+    private Long button;
+    /**
+     * 落地页-关键页面浏览
+     */
+    @Excel(name = "落地页-关键页面浏览", width = 15)
+    @ApiModelProperty(value = "落地页-关键页面浏览")
+    private Long view;
+    /**
+     * 落地页-QQ咨询数
+     */
+    @Excel(name = "落地页-QQ咨询数", width = 15)
+    @ApiModelProperty(value = "落地页-QQ咨询数")
+    private Long qq;
+    /**
+     * 落地页-抽奖数
+     */
+    @Excel(name = "落地页-抽奖数", width = 15)
+    @ApiModelProperty(value = "落地页-抽奖数")
+    private Long lottery;
+    /**
+     * 落地页-投票
+     */
+    @Excel(name = "落地页-投票", width = 15)
+    @ApiModelProperty(value = "落地页-投票")
+    private Long vote;
+    /**
+     * 落地页-页面跳转
+     */
+    @Excel(name = "落地页-页面跳转", width = 15)
+    @ApiModelProperty(value = "落地页-页面跳转")
+    private Long redirect;
+    /**
+     * 落地页-商品购买
+     */
+    @Excel(name = "落地页-商品购买", width = 15)
+    @ApiModelProperty(value = "落地页-商品购买")
+    private Long shopping;
+    /**
+     * 落地页-在线咨询
+     */
+    @Excel(name = "落地页-在线咨询", width = 15)
+    @ApiModelProperty(value = "落地页-在线咨询")
+    private Long consult;
+    /**
+     * 落地页-微信
+     */
+    @Excel(name = "落地页-微信", width = 15)
+    @ApiModelProperty(value = "落地页-微信")
+    private Long wechat;
+    /**
+     * 落地页-智能电话确认拨打
+     */
+    @Excel(name = "落地页-智能电话确认拨打", width = 15)
+    @ApiModelProperty(value = "落地页-智能电话确认拨打")
+    private Long phoneConfirm;
+    /**
+     * 落地页-智能电话确认接通
+     */
+    @Excel(name = "落地页-智能电话确认接通", width = 15)
+    @ApiModelProperty(value = "落地页-智能电话确认接通")
+    private Long phoneConnect;
+    /**
+     * 落地页-智能电话有效咨询
+     */
+    @Excel(name = "落地页-智能电话有效咨询", width = 15)
+    @ApiModelProperty(value = "落地页-智能电话有效咨询")
+    private Long consultEffective;
+    /**
+     * 视频-总播放
+     */
+    @Excel(name = "视频-总播放", width = 15)
+    @ApiModelProperty(value = "视频-总播放")
+    private Long totalPlay;
+    /**
+     * 视频-有效播放
+     */
+    @Excel(name = "视频-有效播放", width = 15)
+    @ApiModelProperty(value = "视频-有效播放")
+    private Long validPlay;
+    /**
+     * 视频-wifi播放
+     */
+    @Excel(name = "视频-wifi播放", width = 15)
+    @ApiModelProperty(value = "视频-wifi播放")
+    private Long wifiPlay;
+    /**
+     * 视频-播放时长,单位ms
+     */
+    @Excel(name = "视频-播放时长,单位ms", width = 15)
+    @ApiModelProperty(value = "视频-播放时长,单位ms")
+    private Long playDurationSum;
+    /**
+     * 视频-播放25%进度总数
+     */
+    @Excel(name = "视频-播放25%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放25%进度总数")
+    private Long play25FeedBreak;
+    /**
+     * 视频-播放50%进度总数
+     */
+    @Excel(name = "视频-播放50%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放50%进度总数")
+    private Long play50FeedBreak;
+    /**
+     * 视频-播放75%进度总数
+     */
+    @Excel(name = "视频-播放75%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放75%进度总数")
+    private Long play75FeedBreak;
+    /**
+     * 视频-播放100%进度总数
+     */
+    @Excel(name = "视频-播放100%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放100%进度总数")
+    private Long play100FeedBreak;
+    /**
+     * 附加创意-电话按钮
+     */
+    @Excel(name = "附加创意-电话按钮", width = 15)
+    @ApiModelProperty(value = "附加创意-电话按钮")
+    private Long advancedCreativePhoneClick;
+    /**
+     * 附加创意-在线咨询
+     */
+    @Excel(name = "附加创意-在线咨询", width = 15)
+    @ApiModelProperty(value = "附加创意-在线咨询")
+    private Long advancedCreativeCounselClick;
+    /**
+     * 附加创意-表单提交
+     */
+    @Excel(name = "附加创意-表单提交", width = 15)
+    @ApiModelProperty(value = "附加创意-表单提交")
+    private Long advancedCreativeFormClick;
+    /**
+     * 互动数据-分享数
+     */
+    @Excel(name = "互动数据-分享数", width = 15)
+    @ApiModelProperty(value = "互动数据-分享数")
+    private Long share;
+    /**
+     * 互动数据-评论数
+     */
+    @Excel(name = "互动数据-评论数", width = 15)
+    @ApiModelProperty(value = "互动数据-评论数")
+    private Long comment;
+    /**
+     * 互动数据-点赞数
+     */
+    @Excel(name = "互动数据-点赞数", width = 15)
+    @ApiModelProperty(value = "互动数据-点赞数")
+    private Long likeNum;
+    /**
+     * 互动数据-关注数
+     */
+    @Excel(name = "互动数据-关注数", width = 15)
+    @ApiModelProperty(value = "互动数据-关注数")
+    private Long follow;
+    /**
+     * 互动数据-主页访问量
+     */
+    @Excel(name = "互动数据-主页访问量", width = 15)
+    @ApiModelProperty(value = "互动数据-主页访问量")
+    private Long homeVisited;
+    /**
+     * 互动数据-挑战赛查看数
+     */
+    @Excel(name = "互动数据-挑战赛查看数", width = 15)
+    @ApiModelProperty(value = "互动数据-挑战赛查看数")
+    private Long iesChallengeClick;
+    /**
+     * 互动数据-音乐查看数
+     */
+    @Excel(name = "互动数据-音乐查看数", width = 15)
+    @ApiModelProperty(value = "互动数据-音乐查看数")
+    private Long iesMusicClick;
+    /**
+     * 互动数据-单次互动成本
+     */
+    @Excel(name = "互动数据-单次互动成本", width = 15)
+    @ApiModelProperty(value = "互动数据-单次互动成本")
+    private BigDecimal interactPerCost;
+    /**
+     * 次留数
+     */
+    @Excel(name = "次留数", width = 15)
+    @ApiModelProperty(value = "次留数")
+    private Long nextDayOpen;
+    /**
+     * 次留率
+     */
+    @Excel(name = "次留率", width = 15)
+    @ApiModelProperty(value = "次留率")
+    private BigDecimal nextDayOpenRate;
+    /**
+     * 次留成本
+     */
+    @Excel(name = "次留成本", width = 15)
+    @ApiModelProperty(value = "次留成本")
+    private BigDecimal nextDayOpenCost;
+    /**
+     * 应用下载广告数据-次留数
+     */
+    private Long attributionNextDayOpenCnt;
+    /**
+     * 应用下载广告数据-次留成本
+     */
+    private BigDecimal attributionNextDayOpenCost;
+    /**
+     * 应用下载广告数据-次留率
+     */
+    private BigDecimal attributionNextDayOpenRate;
+
+    @Excel(name = "创建时间")
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    @Excel(name = "修改时间")
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+
+    public BytedanceAdvertiserDailyReport(JSONObject data) {
+        Long playFeedBreak75 = data.getLong("play_75_feed_break");
+        if (null != playFeedBreak75) {
+            this.play75FeedBreak = playFeedBreak75;
+        }
+        Long nextDayOpen = data.getLong("next_day_open");
+        if (null != nextDayOpen) {
+            this.nextDayOpen = nextDayOpen;
+        }
+        Long convertNum = data.getLong("convert");
+        if (null != convertNum) {
+            this.convertNum = convertNum;
+        }
+        Long inAppCart = data.getLong("in_app_cart");
+        if (null != inAppCart) {
+            this.inAppCart = inAppCart;
+        }
+        Long play25FeedBreak = data.getLong("play_25_feed_break");
+        if (null != play25FeedBreak) {
+            this.play25FeedBreak = play25FeedBreak;
+        }
+        Long consultEffective = data.getLong("consult_effective");
+        if (null != consultEffective) {
+            this.consultEffective = consultEffective;
+        }
+        Long view = data.getLong("view");
+        if (null != view) {
+            this.view = view;
+        }
+        Long phoneConfirm = data.getLong("phone_confirm");
+        if (null != phoneConfirm) {
+            this.phoneConfirm = phoneConfirm;
+        }
+        Long iesMusicClick = data.getLong("ies_music_click");
+        if (null != iesMusicClick) {
+            this.iesMusicClick = iesMusicClick;
+        }
+        Long wifiPlay = data.getLong("wifi_play");
+        if (null != wifiPlay) {
+            this.wifiPlay = wifiPlay;
+        }
+        String statDatetime = data.getString("stat_datetime");
+        if (null != statDatetime && !"".equals(statDatetime.trim())) {
+            this.statDatetime = statDatetime;
+        }
+        Long shopping = data.getLong("shopping");
+        if (null != shopping) {
+            this.shopping = shopping;
+        }
+        Long qq = data.getLong("qq");
+        if (null != qq) {
+            this.qq = qq;
+        }
+        Long like = data.getLong("like");
+        if (null != like) {
+            this.likeNum = like;
+        }
+        Long play50FeedBreak = data.getLong("play_50_feed_break");
+        if (null != play50FeedBreak) {
+            this.play50FeedBreak = play50FeedBreak;
+        }
+        Long active = data.getLong("active");
+        if (null != active) {
+            this.active = active;
+        }
+        Long click = data.getLong("click");
+        if (null != click) {
+            this.click = click;
+        }
+        Long advancedCreativePhoneClick = data.getLong("advanced_creative_phone_click");
+        if (null != advancedCreativePhoneClick) {
+            this.advancedCreativePhoneClick = advancedCreativePhoneClick;
+        }
+        Long downloadStart = data.getLong("download_start");
+        if (null != downloadStart) {
+            this.downloadStart = downloadStart;
+        }
+        Long homeVisited = data.getLong("home_visited");
+        if (null != homeVisited) {
+            this.homeVisited = homeVisited;
+        }
+        Long phone = data.getLong("phone");
+        if (null != phone) {
+            this.phone = phone;
+        }
+        Long inAppPay = data.getLong("in_app_pay");
+        if (null != inAppPay) {
+            this.inAppPay = inAppPay;
+        }
+        BigDecimal nextDayOpenCost = data.getBigDecimal("next_day_open_cost");
+        if (null != nextDayOpenCost) {
+            this.nextDayOpenCost = nextDayOpenCost;
+        }
+        Long iesChallengeClick = data.getLong("ies_challenge_click");
+        if (null != iesChallengeClick) {
+            this.iesChallengeClick = iesChallengeClick;
+        }
+        Long totalPlay = data.getLong("total_play");
+        if (null != totalPlay) {
+            this.totalPlay = totalPlay;
+        }
+        Long show = data.getLong("show");
+        if (null != show) {
+            this.showNum = show;
+        }
+        BigDecimal nextDayOpenRate = data.getBigDecimal("next_day_open_rate");
+        if (null != nextDayOpenRate) {
+            this.nextDayOpenRate = nextDayOpenRate;
+        }
+        Long attributionNextDayOpenCnt = data.getLong("attribution_next_day_open_cnt");
+        if (null != attributionNextDayOpenCnt) {
+            this.attributionNextDayOpenCnt = attributionNextDayOpenCnt;
+        }
+        BigDecimal attributionNextDayOpenCost = data.getBigDecimal("attribution_next_day_open_cost");
+        if (null != attributionNextDayOpenCost) {
+            this.attributionNextDayOpenCost = attributionNextDayOpenCost;
+        }
+        BigDecimal attributionNextDayOpenRate = data.getBigDecimal("attribution_next_day_open_rate");
+        if (null != attributionNextDayOpenRate) {
+            this.attributionNextDayOpenRate = attributionNextDayOpenRate;
+        }
+        Long mapSearch = data.getLong("map_search");
+        if (null != mapSearch) {
+            this.mapSearch = mapSearch;
+        }
+        Long clickInstall = data.getLong("click_install");
+        if (null != clickInstall) {
+            this.clickInstall = clickInstall;
+        }
+        BigDecimal interactPerCost = data.getBigDecimal("interact_per_cost");
+        if (null != interactPerCost) {
+            this.interactPerCost = interactPerCost;
+        }
+        Long advertiserId = data.getLong("advertiser_id");
+        if (null != advertiserId) {
+            this.advertiserId = advertiserId;
+        }
+        Long button = data.getLong("button");
+        if (null != button) {
+            this.button = button;
+        }
+        Long playDurationSum = data.getLong("play_duration_sum");
+        if (null != playDurationSum) {
+            this.playDurationSum = playDurationSum;
+        }
+        Long play100FeedBreak = data.getLong("play_100_feed_break");
+        if (null != play100FeedBreak) {
+            this.play100FeedBreak = play100FeedBreak;
+        }
+        Long advancedCreativeCounselClick = data.getLong("advanced_creative_counsel_click");
+        if (null != advancedCreativeCounselClick) {
+            this.advancedCreativeCounselClick = advancedCreativeCounselClick;
+        }
+        Long share = data.getLong("share");
+        if (null != share) {
+            this.share = share;
+        }
+        Long consult = data.getLong("consult");
+        if (null != consult) {
+            this.consult = consult;
+        }
+        Long vote = data.getLong("vote");
+        if (null != vote) {
+            this.vote = vote;
+        }
+        Long validPlay = data.getLong("valid_play");
+        if (null != validPlay) {
+            this.validPlay = validPlay;
+        }
+        Long redirect = data.getLong("redirect");
+        if (null != redirect) {
+            this.redirect = redirect;
+        }
+        Long payCount = data.getLong("pay_count");
+        if (null != payCount) {
+            this.payCount = payCount;
+        }
+        Long advancedCreativeFormClick = data.getLong("advanced_creative_form_click");
+        if (null != advancedCreativeFormClick) {
+            this.advancedCreativeFormClick = advancedCreativeFormClick;
+        }
+        BigDecimal cost = data.getBigDecimal("cost");
+        if (null != cost) {
+            this.cost = cost;
+        }
+        Long downloadFinish = data.getLong("download_finish");
+        if (null != downloadFinish) {
+            this.downloadFinish = downloadFinish;
+        }
+        Long wechat = data.getLong("wechat");
+        if (null != wechat) {
+            this.wechat = wechat;
+        }
+        Long lottery = data.getLong("lottery");
+        if (null != lottery) {
+            this.lottery = lottery;
+        }
+        Long inAppOrder = data.getLong("in_app_order");
+        if (null != inAppOrder) {
+            this.inAppOrder = inAppOrder;
+        }
+        Long installFinish = data.getLong("install_finish");
+        if (null != installFinish) {
+            this.installFinish = installFinish;
+        }
+        Long follow = data.getLong("follow");
+        if (null != follow) {
+            this.follow = follow;
+        }
+        Long inAppDetailUv = data.getLong("in_app_detail_uv");
+        if (null != inAppDetailUv) {
+            this.inAppDetailUv = inAppDetailUv;
+        }
+        Long form = data.getLong("form");
+        if (null != form) {
+            this.form = form;
+        }
+        Long comment = data.getLong("comment");
+        if (null != comment) {
+            this.comment = comment;
+        }
+        Long inAppUv = data.getLong("in_app_uv");
+        if (null != inAppUv) {
+            this.inAppUv = inAppUv;
+        }
+        Long register = data.getLong("register");
+        if (null != register) {
+            this.register = register;
+        }
+        this.createTime = new Date();
+        this.updateTime = new Date();
+        this.id = "" + this.advertiserId + this.statDatetime.substring(0, 10);
+    }
+
+    public BytedanceAdvertiserDailyReport() {
+    }
+}

+ 638 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/BytedanceAdvertiserHourlyReport.java

@@ -0,0 +1,638 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import cn.com.ctop.job.bytedance.utils.DateUtils;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+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 java.math.BigDecimal;
+import java.text.ParseException;
+import java.util.Date;
+
+/**
+ * 广告主小时级别报表信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2019-09-10
+ */
+@Data
+@TableName("ctop_bytedance_report_advertiser_hourly")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_bytedance_report_advertiser_hourly对象", description = "广告主小时级别报表信息")
+public class BytedanceAdvertiserHourlyReport {
+
+    /**
+     * id
+     */
+    @TableId
+    @ApiModelProperty(value = "id")
+    private String id;
+    /**
+     * 广告主id
+     */
+    @Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+    private Long advertiserId;
+    /**
+     * 数据起始时间
+     */
+    @Excel(name = "数据起始时间", width = 15)
+    @ApiModelProperty(value = "数据起始时间")
+    private String statDatetime;
+
+
+    private Integer statHour;
+    /**
+     * 展示量
+     */
+    @Excel(name = "展示量", width = 15)
+    @ApiModelProperty(value = "展示量")
+    private Long showNum;
+    /**
+     * 点击量
+     */
+    @Excel(name = "点击量", width = 15)
+    @ApiModelProperty(value = "点击量")
+    private Long click;
+    /**
+     * 转化量
+     */
+    @Excel(name = "转化量", width = 15)
+    @ApiModelProperty(value = "转化量")
+    private Long convertNum;
+    /**
+     * 总花费
+     */
+    @Excel(name = "总花费", width = 15)
+    @ApiModelProperty(value = "总花费")
+    private BigDecimal cost;
+    /**
+     * 应用下载-激活
+     */
+    @Excel(name = "应用下载-激活", width = 15)
+    @ApiModelProperty(value = "应用下载-激活")
+    private Long active;
+    /**
+     * 应用下载-安卓下载完成
+     */
+    @Excel(name = "应用下载-安卓下载完成", width = 15)
+    @ApiModelProperty(value = "应用下载-安卓下载完成")
+    private Long downloadFinish;
+    /**
+     * 应用下载-安卓下载开始
+     */
+    @Excel(name = "应用下载-安卓下载开始", width = 15)
+    @ApiModelProperty(value = "应用下载-安卓下载开始")
+    private Long downloadStart;
+    /**
+     * 应用下载-点击安装数
+     */
+    @Excel(name = "应用下载-点击安装数", width = 15)
+    @ApiModelProperty(value = "应用下载-点击安装数")
+    private Long clickInstall;
+    /**
+     * 应用下载-安卓安装完成
+     */
+    @Excel(name = "应用下载-安卓安装完成", width = 15)
+    @ApiModelProperty(value = "应用下载-安卓安装完成")
+    private Long installFinish;
+    /**
+     * 应用下载-注册
+     */
+    @Excel(name = "应用下载-注册", width = 15)
+    @ApiModelProperty(value = "应用下载-注册")
+    private Long register;
+    /**
+     * 应用下载-付费数
+     */
+    @Excel(name = "应用下载-付费数", width = 15)
+    @ApiModelProperty(value = "应用下载-付费数")
+    private Long payCount;
+    /**
+     * 应用下载-到达uv
+     */
+    @Excel(name = "应用下载-到达uv", width = 15)
+    @ApiModelProperty(value = "应用下载-到达uv")
+    private Long inAppUv;
+    /**
+     * 应用下载-详情页到站uv
+     */
+    @Excel(name = "应用下载-详情页到站uv", width = 15)
+    @ApiModelProperty(value = "应用下载-详情页到站uv")
+    private Long inAppDetailUv;
+    /**
+     * 应用下载-加入购物车
+     */
+    @Excel(name = "应用下载-加入购物车", width = 15)
+    @ApiModelProperty(value = "应用下载-加入购物车")
+    private Long inAppCart;
+    /**
+     * 应用下载-提交订单
+     */
+    @Excel(name = "应用下载-提交订单", width = 15)
+    @ApiModelProperty(value = "应用下载-提交订单")
+    private Long inAppOrder;
+    /**
+     * 应用下载-付费
+     */
+    @Excel(name = "应用下载-付费", width = 15)
+    @ApiModelProperty(value = "应用下载-付费")
+    private Long inAppPay;
+    /**
+     * 落地页-电话拨打数
+     */
+    @Excel(name = "落地页-电话拨打数", width = 15)
+    @ApiModelProperty(value = "落地页-电话拨打数")
+    private Long phone;
+    /**
+     * 表单提交数
+     */
+    @Excel(name = "表单提交数", width = 15)
+    @ApiModelProperty(value = "表单提交数")
+    private Long form;
+    /**
+     * 落地页-地图搜索
+     */
+    @Excel(name = "落地页-地图搜索", width = 15)
+    @ApiModelProperty(value = "落地页-地图搜索")
+    private Long mapSearch;
+    /**
+     * 落地页-按钮button
+     */
+    @Excel(name = "落地页-按钮button", width = 15)
+    @ApiModelProperty(value = "落地页-按钮button")
+    private Long button;
+    /**
+     * 落地页-关键页面浏览
+     */
+    @Excel(name = "落地页-关键页面浏览", width = 15)
+    @ApiModelProperty(value = "落地页-关键页面浏览")
+    private Long view;
+    /**
+     * 落地页-QQ咨询数
+     */
+    @Excel(name = "落地页-QQ咨询数", width = 15)
+    @ApiModelProperty(value = "落地页-QQ咨询数")
+    private Long qq;
+    /**
+     * 落地页-抽奖数
+     */
+    @Excel(name = "落地页-抽奖数", width = 15)
+    @ApiModelProperty(value = "落地页-抽奖数")
+    private Long lottery;
+    /**
+     * 落地页-投票
+     */
+    @Excel(name = "落地页-投票", width = 15)
+    @ApiModelProperty(value = "落地页-投票")
+    private Long vote;
+    /**
+     * 落地页-页面跳转
+     */
+    @Excel(name = "落地页-页面跳转", width = 15)
+    @ApiModelProperty(value = "落地页-页面跳转")
+    private Long redirect;
+    /**
+     * 落地页-商品购买
+     */
+    @Excel(name = "落地页-商品购买", width = 15)
+    @ApiModelProperty(value = "落地页-商品购买")
+    private Long shopping;
+    /**
+     * 落地页-在线咨询
+     */
+    @Excel(name = "落地页-在线咨询", width = 15)
+    @ApiModelProperty(value = "落地页-在线咨询")
+    private Long consult;
+    /**
+     * 落地页-微信
+     */
+    @Excel(name = "落地页-微信", width = 15)
+    @ApiModelProperty(value = "落地页-微信")
+    private Long wechat;
+    /**
+     * 落地页-智能电话确认拨打
+     */
+    @Excel(name = "落地页-智能电话确认拨打", width = 15)
+    @ApiModelProperty(value = "落地页-智能电话确认拨打")
+    private Long phoneConfirm;
+    /**
+     * 落地页-智能电话确认接通
+     */
+    @Excel(name = "落地页-智能电话确认接通", width = 15)
+    @ApiModelProperty(value = "落地页-智能电话确认接通")
+    private Long phoneConnect;
+    /**
+     * 落地页-智能电话有效咨询
+     */
+    @Excel(name = "落地页-智能电话有效咨询", width = 15)
+    @ApiModelProperty(value = "落地页-智能电话有效咨询")
+    private Long consultEffective;
+    /**
+     * 视频-总播放
+     */
+    @Excel(name = "视频-总播放", width = 15)
+    @ApiModelProperty(value = "视频-总播放")
+    private Long totalPlay;
+    /**
+     * 视频-有效播放
+     */
+    @Excel(name = "视频-有效播放", width = 15)
+    @ApiModelProperty(value = "视频-有效播放")
+    private Long validPlay;
+    /**
+     * 视频-wifi播放
+     */
+    @Excel(name = "视频-wifi播放", width = 15)
+    @ApiModelProperty(value = "视频-wifi播放")
+    private Long wifiPlay;
+    /**
+     * 视频-播放时长,单位ms
+     */
+    @Excel(name = "视频-播放时长,单位ms", width = 15)
+    @ApiModelProperty(value = "视频-播放时长,单位ms")
+    private Long playDurationSum;
+    /**
+     * 视频-播放25%进度总数
+     */
+    @Excel(name = "视频-播放25%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放25%进度总数")
+    private Long play25FeedBreak;
+    /**
+     * 视频-播放50%进度总数
+     */
+    @Excel(name = "视频-播放50%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放50%进度总数")
+    private Long play50FeedBreak;
+    /**
+     * 视频-播放75%进度总数
+     */
+    @Excel(name = "视频-播放75%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放75%进度总数")
+    private Long play75FeedBreak;
+    /**
+     * 视频-播放100%进度总数
+     */
+    @Excel(name = "视频-播放100%进度总数", width = 15)
+    @ApiModelProperty(value = "视频-播放100%进度总数")
+    private Long play100FeedBreak;
+    /**
+     * 附加创意-电话按钮
+     */
+    @Excel(name = "附加创意-电话按钮", width = 15)
+    @ApiModelProperty(value = "附加创意-电话按钮")
+    private Long advancedCreativePhoneClick;
+    /**
+     * 附加创意-在线咨询
+     */
+    @Excel(name = "附加创意-在线咨询", width = 15)
+    @ApiModelProperty(value = "附加创意-在线咨询")
+    private Long advancedCreativeCounselClick;
+    /**
+     * 附加创意-表单提交
+     */
+    @Excel(name = "附加创意-表单提交", width = 15)
+    @ApiModelProperty(value = "附加创意-表单提交")
+    private Long advancedCreativeFormClick;
+    /**
+     * 互动数据-分享数
+     */
+    @Excel(name = "互动数据-分享数", width = 15)
+    @ApiModelProperty(value = "互动数据-分享数")
+    private Long share;
+    /**
+     * 互动数据-评论数
+     */
+    @Excel(name = "互动数据-评论数", width = 15)
+    @ApiModelProperty(value = "互动数据-评论数")
+    private Long comment;
+    /**
+     * 互动数据-点赞数
+     */
+    @Excel(name = "互动数据-点赞数", width = 15)
+    @ApiModelProperty(value = "互动数据-点赞数")
+    private Long likeNum;
+    /**
+     * 互动数据-关注数
+     */
+    @Excel(name = "互动数据-关注数", width = 15)
+    @ApiModelProperty(value = "互动数据-关注数")
+    private Long follow;
+    /**
+     * 互动数据-主页访问量
+     */
+    @Excel(name = "互动数据-主页访问量", width = 15)
+    @ApiModelProperty(value = "互动数据-主页访问量")
+    private Long homeVisited;
+    /**
+     * 互动数据-挑战赛查看数
+     */
+    @Excel(name = "互动数据-挑战赛查看数", width = 15)
+    @ApiModelProperty(value = "互动数据-挑战赛查看数")
+    private Long iesChallengeClick;
+    /**
+     * 互动数据-音乐查看数
+     */
+    @Excel(name = "互动数据-音乐查看数", width = 15)
+    @ApiModelProperty(value = "互动数据-音乐查看数")
+    private Long iesMusicClick;
+    /**
+     * 互动数据-单次互动成本
+     */
+    @Excel(name = "互动数据-单次互动成本", width = 15)
+    @ApiModelProperty(value = "互动数据-单次互动成本")
+    private BigDecimal interactPerCost;
+    /**
+     * 次留数
+     */
+    @Excel(name = "次留数", width = 15)
+    @ApiModelProperty(value = "次留数")
+    private Long nextDayOpen;
+
+    /**
+     * 次留率
+     */
+    @Excel(name = "次留率", width = 15)
+    @ApiModelProperty(value = "次留率")
+    private BigDecimal nextDayOpenRate;
+    /**
+     * 次留成本
+     */
+    @Excel(name = "次留成本", width = 15)
+    @ApiModelProperty(value = "次留成本")
+    private BigDecimal nextDayOpenCost;
+    /**
+     * 应用下载广告数据-次留数
+     */
+    private Long attributionNextDayOpenCnt;
+    /**
+     * 应用下载广告数据-次留成本
+     */
+    private BigDecimal attributionNextDayOpenCost;
+    /**
+     * 应用下载广告数据-次留率
+     */
+    private BigDecimal attributionNextDayOpenRate;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    public BytedanceAdvertiserHourlyReport(JSONObject data) {
+        Long getPlayFeedBreak75 = data.getLong("play_75_feed_break");
+        if (null != getPlayFeedBreak75) {
+            this.play75FeedBreak = getPlayFeedBreak75;
+        }
+        Long getNextDayOpen = data.getLong("next_day_open");
+        if (null != getNextDayOpen) {
+            this.nextDayOpen = getNextDayOpen;
+        }
+        Long getConvertNum = data.getLong("convert");
+        if (null != getConvertNum) {
+            this.convertNum = getConvertNum;
+        }
+        Long getInAppCart = data.getLong("in_app_cart");
+        if (null != getInAppCart) {
+            this.inAppCart = getInAppCart;
+        }
+        Long getPlay25FeedBreak = data.getLong("play_25_feed_break");
+        if (null != getPlay25FeedBreak) {
+            this.play25FeedBreak = getPlay25FeedBreak;
+        }
+        Long getConsultEffective = data.getLong("consult_effective");
+        if (null != getConsultEffective) {
+            this.consultEffective = getConsultEffective;
+        }
+        Long getView = data.getLong("view");
+        if (null != getView) {
+            this.view = getView;
+        }
+        Long getPhoneConfirm = data.getLong("phone_confirm");
+        if (null != getPhoneConfirm) {
+            this.phoneConfirm = getPhoneConfirm;
+        }
+        Long getIesMusicClick = data.getLong("ies_music_click");
+        if (null != getIesMusicClick) {
+            this.iesMusicClick = getIesMusicClick;
+        }
+        Long getWifiPlay = data.getLong("wifi_play");
+        if (null != getWifiPlay) {
+            this.wifiPlay = getWifiPlay;
+        }
+        String getStatDatetime = data.getString("stat_datetime");
+        if (null != getStatDatetime && !"".equals(getStatDatetime.trim())) {
+            try {
+                this.statDatetime = DateUtils.getDateByDateStr(getStatDatetime);
+                this.statHour = DateUtils.getHour(getStatDatetime);
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+        }
+        Long getShopping = data.getLong("shopping");
+        if (null != getShopping) {
+            this.shopping = getShopping;
+        }
+        Long getQq = data.getLong("qq");
+        if (null != getQq) {
+            this.qq = getQq;
+        }
+        Long getLike = data.getLong("like");
+        if (null != getLike) {
+            this.likeNum = getLike;
+        }
+        Long getPlay50FeedBreak = data.getLong("play_50_feed_break");
+        if (null != getPlay50FeedBreak) {
+            this.play50FeedBreak = getPlay50FeedBreak;
+        }
+        Long getActive = data.getLong("active");
+        if (null != getActive) {
+            this.active = getActive;
+        }
+        Long getClick = data.getLong("click");
+        if (null != getClick) {
+            this.click = getClick;
+        }
+        Long getAdvancedCreativePhoneClick = data.getLong("advanced_creative_phone_click");
+        if (null != getAdvancedCreativePhoneClick) {
+            this.advancedCreativePhoneClick = getAdvancedCreativePhoneClick;
+        }
+        Long getDownloadStart = data.getLong("download_start");
+        if (null != getDownloadStart) {
+            this.downloadStart = getDownloadStart;
+        }
+        Long getHomeVisited = data.getLong("home_visited");
+        if (null != getHomeVisited) {
+            this.homeVisited = getHomeVisited;
+        }
+        Long getPhone = data.getLong("phone");
+        if (null != getPhone) {
+            this.phone = getPhone;
+        }
+        Long getInAppPay = data.getLong("in_app_pay");
+        if (null != getInAppPay) {
+            this.inAppPay = getInAppPay;
+        }
+        BigDecimal getNextDayOpenCost = data.getBigDecimal("next_day_open_cost");
+        if (null != getNextDayOpenCost) {
+            this.nextDayOpenCost = getNextDayOpenCost;
+        }
+        Long getIesChallengeClick = data.getLong("ies_challenge_click");
+        if (null != getIesChallengeClick) {
+            this.iesChallengeClick = getIesChallengeClick;
+        }
+        Long getTotalPlay = data.getLong("total_play");
+        if (null != getTotalPlay) {
+            this.totalPlay = getTotalPlay;
+        }
+        Long getShow = data.getLong("show");
+        if (null != getShow) {
+            this.showNum = getShow;
+        }
+        BigDecimal getNextDayOpenRate = data.getBigDecimal("next_day_open_rate");
+        if (null != getNextDayOpenRate) {
+            this.nextDayOpenRate = getNextDayOpenRate;
+        }
+        Long attributionNextDayOpenCnt = data.getLong("attribution_next_day_open_cnt");
+        if (null != attributionNextDayOpenCnt) {
+            this.attributionNextDayOpenCnt = attributionNextDayOpenCnt;
+        }
+        BigDecimal attributionNextDayOpenCost = data.getBigDecimal("attribution_next_day_open_cost");
+        if (null != attributionNextDayOpenCost) {
+            this.attributionNextDayOpenCost = attributionNextDayOpenCost;
+        }
+        BigDecimal attributionNextDayOpenRate = data.getBigDecimal("attribution_next_day_open_rate");
+        if (null != attributionNextDayOpenRate) {
+            this.attributionNextDayOpenRate = attributionNextDayOpenRate;
+        }
+        Long getMapSearch = data.getLong("map_search");
+        if (null != getMapSearch) {
+            this.mapSearch = getMapSearch;
+        }
+        Long getClickInstall = data.getLong("click_install");
+        if (null != getClickInstall) {
+            this.clickInstall = getClickInstall;
+        }
+        BigDecimal getInteractPerCost = data.getBigDecimal("interact_per_cost");
+        if (null != getInteractPerCost) {
+            this.interactPerCost = getInteractPerCost;
+        }
+        Long getAdvertiserId = data.getLong("advertiser_id");
+        if (null != getAdvertiserId) {
+            this.advertiserId = getAdvertiserId;
+        }
+        Long getButton = data.getLong("button");
+        if (null != getButton) {
+            this.button = getButton;
+        }
+        Long getPlayDurationSum = data.getLong("play_duration_sum");
+        if (null != getPlayDurationSum) {
+            this.playDurationSum = getPlayDurationSum;
+        }
+        Long getPlay100FeedBreak = data.getLong("play_100_feed_break");
+        if (null != getPlay100FeedBreak) {
+            this.play100FeedBreak = getPlay100FeedBreak;
+        }
+        Long getAdvancedCreativeCounselClick = data.getLong("advanced_creative_counsel_click");
+        if (null != getAdvancedCreativeCounselClick) {
+            this.advancedCreativeCounselClick = getAdvancedCreativeCounselClick;
+        }
+        Long getShare = data.getLong("share");
+        if (null != getShare) {
+            this.share = getShare;
+        }
+        Long getConsult = data.getLong("consult");
+        if (null != getConsult) {
+            this.consult = getConsult;
+        }
+        Long getVote = data.getLong("vote");
+        if (null != getVote) {
+            this.vote = getVote;
+        }
+        Long getValidPlay = data.getLong("valid_play");
+        if (null != getValidPlay) {
+            this.validPlay = getValidPlay;
+        }
+        Long getRedirect = data.getLong("redirect");
+        if (null != getRedirect) {
+            this.redirect = getRedirect;
+        }
+        Long getPayCount = data.getLong("pay_count");
+        if (null != getPayCount) {
+            this.payCount = getPayCount;
+        }
+        Long getAdvancedCreativeFormClick = data.getLong("advanced_creative_form_click");
+        if (null != getAdvancedCreativeFormClick) {
+            this.advancedCreativeFormClick = getAdvancedCreativeFormClick;
+        }
+        BigDecimal getCost = data.getBigDecimal("cost");
+        if (null != getCost) {
+            this.cost = getCost;
+        }
+        Long getDownloadFinish = data.getLong("download_finish");
+        if (null != getDownloadFinish) {
+            this.downloadFinish = getDownloadFinish;
+        }
+        Long getWechat = data.getLong("wechat");
+        if (null != getWechat) {
+            this.wechat = getWechat;
+        }
+        Long getLottery = data.getLong("lottery");
+        if (null != getLottery) {
+            this.lottery = getLottery;
+        }
+        Long getInAppOrder = data.getLong("in_app_order");
+        if (null != getInAppOrder) {
+            this.inAppOrder = getInAppOrder;
+        }
+        Long getInstallFinish = data.getLong("install_finish");
+        if (null != getInstallFinish) {
+            this.installFinish = getInstallFinish;
+        }
+        Long getFollow = data.getLong("follow");
+        if (null != getFollow) {
+            this.follow = getFollow;
+        }
+        Long getInAppDetailUv = data.getLong("in_app_detail_uv");
+        if (null != getInAppDetailUv) {
+            this.inAppDetailUv = getInAppDetailUv;
+        }
+        Long getForm = data.getLong("form");
+        if (null != getForm) {
+            this.form = getForm;
+        }
+        Long getComment = data.getLong("comment");
+        if (null != getComment) {
+            this.comment = getComment;
+        }
+        Long getInAppUv = data.getLong("in_app_uv");
+        if (null != getInAppUv) {
+            this.inAppUv = getInAppUv;
+        }
+        Long getRegister = data.getLong("register");
+        if (null != getRegister) {
+            this.register = getRegister;
+        }
+        this.id = "" + advertiserId + this.statDatetime + "_" + this.statHour;
+        this.createTime = new Date();
+        this.updateTime = new Date();
+    }
+
+    public BytedanceAdvertiserHourlyReport() {
+    }
+
+
+}

+ 61 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/BytedanceAgentToken.java

@@ -0,0 +1,61 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 代理商token
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-08-18
+ */
+@Data
+public class BytedanceAgentToken {
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "主键ID")
+    private String id;
+
+    private String agentId;
+    private String agentName;
+    /**
+     * 访问令牌
+     */
+    private String accessToken;
+    /**
+     * 访问令牌有效期
+     */
+    private Date accessTokenExpiresIn;
+    /**
+     * 刷新令牌
+     */
+    private String refreshToken;
+    /**
+     * 刷新令牌有效期
+     */
+    private Date refreshTokenExpiresIn;
+    /**
+     * 代理商类型 0:三方代理商 1:本代理商
+     */
+    private Integer agentType;
+
+
+    private Long appId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+}

+ 167 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/CtopOauthToken.java

@@ -0,0 +1,167 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.alibaba.fastjson.JSONObject;
+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.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * @Description: oauth授权码
+ * @Author: jeecg-boot
+ * @Date: 2019-07-09
+ * @Version: V1.0
+ */
+@Data
+@TableName("ctop_oauth_token")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_oauth_token对象", description = "oauth授权码")
+public class CtopOauthToken {
+
+    /**
+     * 主键ID
+     */
+    @TableId()
+    @ApiModelProperty(value = "主键ID")
+    private String id;
+    /**
+     * 媒体ID(外部广告平台类型,快手/头条/抖音等)
+     */
+    @Excel(name = "媒体ID(外部广告平台类型,快手/头条/抖音等)", width = 15)
+    @ApiModelProperty(value = "媒体ID(外部广告平台类型,快手/头条/抖音等)")
+    private String mediaId;
+    /**
+     * 广告主ID(自己平台用户内部id)
+     */
+    @Excel(name = "广告主ID(自己平台用户内部id)", width = 15)
+    @ApiModelProperty(value = "广告主ID(自己平台用户内部id)")
+    private String advertiserId;
+    /**
+     * 广告账户ID(相当于头条返回的access_token数据中的advertiser_id)
+     */
+    @Excel(name = "广告账户ID(相当于头条返回的access_token数据中的advertiser_id)", width = 15)
+    @ApiModelProperty(value = "广告账户ID(相当于头条返回的access_token数据中的advertiser_id)")
+    private Long accountId;
+    /**
+     * 访问令牌
+     */
+    @Excel(name = "访问令牌", width = 15)
+    @ApiModelProperty(value = "访问令牌")
+    private String accessToken;
+    /**
+     * 访问令牌有效期
+     */
+    @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 accessTokenExpiresIn;
+    /**
+     * 刷新令牌
+     */
+    @Excel(name = "刷新令牌", width = 15)
+    @ApiModelProperty(value = "刷新令牌")
+    private String refreshToken;
+
+
+    private Integer agentType;
+    private Long appId;
+
+    /**
+     * 刷新令牌有效期
+     */
+    @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 refreshTokenExpiresIn;
+
+
+    /**
+     * 创建时间
+     */
+    @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;
+
+    public CtopOauthToken(String userId, JSONObject data) {
+        Long accountId = data.getLong("advertiser_id");
+        this.id = String.valueOf(accountId);
+        this.advertiserId = userId;
+        this.mediaId = "1";
+        this.accountId = accountId;
+        String accessToken = data.getString("access_token");
+        Integer refreshTokenExpiresIn = data.getInteger("refresh_token_expires_in");
+        Integer expiresIn = data.getInteger("expires_in");
+        String refreshToken = data.getString("refresh_token");
+        this.accessToken = accessToken;
+        this.refreshToken = refreshToken;
+        Date now = new Date();
+        this.accessTokenExpiresIn = addSecond(now, expiresIn);
+        this.refreshTokenExpiresIn = addSecond(now, refreshTokenExpiresIn);
+        this.createTime = now;
+        this.updateTime = now;
+    }
+
+    public CtopOauthToken() {
+    }
+
+    public CtopOauthToken(CtopOauthToken token, JSONObject data) {
+        this.advertiserId = token.getAdvertiserId();
+        this.mediaId = "1";
+        this.accountId = token.getAccountId();
+        String accessToken = data.getString("access_token");
+        Integer refreshTokenExpiresIn = data.getInteger("refresh_token_expires_in");
+        Integer expiresIn = data.getInteger("expires_in");
+        String refreshToken = data.getString("refresh_token");
+        this.accessToken = accessToken;
+        this.refreshToken = refreshToken;
+        Date now = new Date();
+        this.accessTokenExpiresIn = addSecond(now, expiresIn);
+        this.refreshTokenExpiresIn = addSecond(now, refreshTokenExpiresIn);
+        this.updateTime = now;
+    }
+
+    private static Date addSecond(Date date, int seconds) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.SECOND, seconds);
+        return calendar.getTime();
+    }
+
+    @Override
+    public String toString() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return id +
+                "," + mediaId +
+                "," + advertiserId +
+                "," + accountId +
+                "," + accessToken +
+                "," + sdf.format(accessTokenExpiresIn) +
+                "," + refreshToken +
+                "," + sdf.format(refreshTokenExpiresIn) +
+                "," + sdf.format(createTime) +
+                "," + sdf.format(updateTime);
+    }
+}

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

@@ -0,0 +1,153 @@
+package cn.com.ctop.job.bytedance.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;
+}

+ 59 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleAccountTemplate.java

@@ -0,0 +1,59 @@
+package cn.com.ctop.job.bytedance.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 io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 规则模板
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-11-15
+ */
+@Data
+@TableName("ctop_rule_account_template")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_rule_account_template对象", description = "规则模板")
+public class RuleAccountTemplate {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 账户id
+     */
+    @Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
+    private Long accountId;
+    /**
+     * 模板id
+     */
+    @Excel(name = "模板id", width = 15)
+    @ApiModelProperty(value = "模板id")
+    private Long templateId;
+    private Integer templateStatus;
+
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 75 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataAccount.java

@@ -0,0 +1,75 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+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 java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 规则账户清洗数据
+ * @author jeecg-boot
+ * @date   2020-11-16
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_rule_data_account")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_rule_data_account对象", description="规则账户清洗数据")
+public class RuleDataAccount {
+
+	/**id*/
+    @ApiModelProperty(value = "id")
+	private Long id;
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
+	private Long accountId;
+	/**账户name*/
+	@Excel(name = "账户id", width = 15)
+	@ApiModelProperty(value = "账户id")
+	private String accountName;
+	/**消耗*/
+	@Excel(name = "消耗", width = 15)
+    @ApiModelProperty(value = "消耗")
+	private BigDecimal cost;
+	/**validBalance*/
+	@Excel(name = "validBalance", width = 15)
+    @ApiModelProperty(value = "validBalance")
+	private BigDecimal validBalance;
+	/**转化数*/
+	@Excel(name = "转化数", width = 15)
+    @ApiModelProperty(value = "转化数")
+	private Long convertNum;
+	/**转化成本*/
+	@Excel(name = "转化成本", width = 15)
+    @ApiModelProperty(value = "转化成本")
+	private BigDecimal convertCost;
+	/**次留数*/
+	@Excel(name = "次留数", width = 15)
+    @ApiModelProperty(value = "次留数")
+	private Long nextDayOpenNum;
+	/**nextDayOpenCost*/
+	@Excel(name = "nextDayOpenCost", width = 15)
+    @ApiModelProperty(value = "nextDayOpenCost")
+	private BigDecimal nextDayOpenCost;
+
+	private BigDecimal nextDayOpenRate;
+
+	/**status*/
+	@Excel(name = "status", width = 15)
+    @ApiModelProperty(value = "status")
+	private Integer status;
+	/**createTime*/
+    @ApiModelProperty(value = "createTime")
+	private Date createTime;
+	/**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+	private Date updateTime;
+}

+ 41 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataCreative.java

@@ -0,0 +1,41 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 规则创意清洗数据
+ * @author jeecg-boot
+ * @date   2020-11-16
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_rule_data_creative")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_rule_data_creative对象", description="规则创意清洗数据")
+public class RuleDataCreative {
+
+	@TableId
+	private Long id;
+	private Long accountId;
+	private String accountName;
+	private Long planId;
+	private String planName;
+	private Long creativeId;
+	private Integer presentedVideo;
+	private String creativeTitle;
+	private String source;
+	private Integer status;
+	private Date createTime;
+	private Date updateTime;
+
+	public RuleDataCreative() {
+	}
+}

+ 95 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataPlan.java

@@ -0,0 +1,95 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 规则计划清洗数据
+ * @author jeecg-boot
+ * @date   2020-11-16
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_rule_data_plan")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_rule_data_plan对象", description="规则计划清洗数据")
+public class RuleDataPlan {
+
+	@TableId
+	private Long id;
+	private Long accountId;
+	private String accountName;
+	private Long planId;
+	private String planName;
+	private String externalUrl;
+	private String downloadUrl;
+	private BigDecimal cost;
+	private Long convertNum;
+	private Long convertId;
+	private String deepConvertTarget;
+	private BigDecimal convertCost;
+	private BigDecimal nextDayOpenRate;
+	private BigDecimal nextDayOpenCost;
+	private Long nextDayOpen;
+	private String pricing;
+	private BigDecimal budget;
+	private Integer status;
+	private BigDecimal cpaBid;
+	private BigDecimal deepCpabid;
+	private Date createTime;
+	private Date updateTime;
+
+	public RuleDataPlan() {
+	}
+
+	public RuleDataPlan(JSONObject data, Long accountId) {
+		Long nextDayOpen = data.getLong("attribution_next_day_open_cnt");
+		if (null != nextDayOpen) {
+			this.nextDayOpen = nextDayOpen;
+		}
+		Long convert = data.getLong("convert");
+		if (null != convert) {
+			this.convertNum = convert;
+		}
+		BigDecimal nextDayOpenCost = data.getBigDecimal("attribution_next_day_open_cost");
+		if (null != nextDayOpenCost) {
+			this.nextDayOpenCost = nextDayOpenCost;
+		}
+
+		BigDecimal nextDayOpenRate = data.getBigDecimal("attribution_next_day_open_rate");
+		if (null != nextDayOpenRate) {
+			this.nextDayOpenRate = nextDayOpenRate;
+		}
+		this.accountId = accountId;
+		BigDecimal cost = data.getBigDecimal("cost");
+		if (null != cost) {
+			this.cost = cost;
+		}
+		BigDecimal convertCost = data.getBigDecimal("convert_cost");
+		if (null != convertCost) {
+			this.convertCost = convertCost;
+		}
+		String adName = data.getString("ad_name");
+		if (null != adName) {
+			this.planName = adName;
+		}
+		Long adId = data.getLong("ad_id");
+		this.id = adId;
+		this.planId = adId;
+		this.createTime = new Date();
+		this.updateTime = new Date();
+	}
+
+
+
+
+}

+ 78 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/RuleDataTarget.java

@@ -0,0 +1,78 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+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 java.util.Date;
+
+/**
+ * 规则定向清洗数据
+ * @author jeecg-boot
+ * @date   2020-11-16
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_rule_data_target")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_rule_data_target对象", description="规则定向清洗数据")
+public class RuleDataTarget {
+
+	@TableId
+	private Long id;
+	private Long accountId;
+	private String accountName;
+	private Long planId;
+	private String planName;
+
+	/**retargetingTagsExclude*/
+	private String retargetingTagsExclude;
+	private String retargetingTagsInclude;
+
+	/**hideIfExists*/
+	@Excel(name = "hideIfExists", width = 15)
+    @ApiModelProperty(value = "hideIfExists")
+	private Integer hideIfExists;
+	/**inventoryType*/
+	@Excel(name = "inventoryType", width = 15)
+    @ApiModelProperty(value = "inventoryType")
+	private String inventoryType;
+	/**district*/
+	@Excel(name = "district", width = 15)
+    @ApiModelProperty(value = "district")
+	private String district;
+	/**gender*/
+	@Excel(name = "gender", width = 15)
+    @ApiModelProperty(value = "gender")
+	private String gender;
+	/**age*/
+	@Excel(name = "age", width = 15)
+    @ApiModelProperty(value = "age")
+	private String age;
+	/**excludeFlowPackage*/
+	@Excel(name = "excludeFlowPackage", width = 15)
+    @ApiModelProperty(value = "excludeFlowPackage")
+	private String excludeFlowPackage;
+	/**platform*/
+	@Excel(name = "platform", width = 15)
+    @ApiModelProperty(value = "platform")
+	private String platform;
+	/**hideIfConverted*/
+	@Excel(name = "hideIfConverted", width = 15)
+    @ApiModelProperty(value = "hideIfConverted")
+	private String hideIfConverted;
+	private String deepBidType;
+	private String scheduleTime;
+	private Integer status;
+	private Date createTime;
+	private Date updateTime;
+
+	public RuleDataTarget() {
+	}
+}

+ 33 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/TransactionDay.java

@@ -0,0 +1,33 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import lombok.Data;
+
+@Data
+public class TransactionDay {
+    //
+    private String id;
+    //广告主ID
+    private String advertiserId;
+    //日期
+    private String date;
+    //日终结余(单位元)
+    private String balance;
+    //现金支出(单位元)
+    private String cashCost;
+    //总支出(单位元)
+    private String cost;
+    //冻结(单位元)
+    private String frozen;
+    //总存入(单位元)
+    private String income;
+    //赠款支出(单位元)
+    private String rewardCost;
+    //共享钱包支出(单位元)
+    private String sharedWalletCost;
+    //总转入(单位元)
+    private String transferIn;
+    //总转出(单位元)
+    private String transferOut;
+    //创建时间
+    private String createTime;
+}

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

@@ -0,0 +1,171 @@
+package cn.com.ctop.job.bytedance.entity;
+
+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.io.Serializable;
+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 implements Serializable {
+
+    /**
+     * 主键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
+     */
+    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;*/
+
+}

+ 75 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WarningOperationLog.java

@@ -0,0 +1,75 @@
+package cn.com.ctop.job.bytedance.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 io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 预警操作记录
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-11-11
+ */
+@Data
+@TableName("ctop_warning_operation_log")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_warning_operation_log对象", description = "预警操作记录")
+public class WarningOperationLog {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 账户ID
+     */
+    @Excel(name = "账户ID", width = 15)
+    @ApiModelProperty(value = "账户ID")
+    private Long accountId;
+    /**
+     * 账户ID
+     */
+    @Excel(name = "账户ID", width = 15)
+    @ApiModelProperty(value = "账户ID")
+    private Long unitId;
+    /**
+     * 发送人
+     */
+    @Excel(name = "发送人", width = 15)
+    @ApiModelProperty(value = "发送人")
+    private String userId;
+    /**
+     * 标题
+     */
+    @Excel(name = "标题", width = 15)
+    @ApiModelProperty(value = "标题")
+    private String subject;
+    /**
+     * 预警类型 1 出价方式  2 出价过高
+     */
+    @Excel(name = "预警类型 1 出价方式  2 出价过高 ", width = 15)
+    @ApiModelProperty(value = "预警类型 1 出价方式  2 出价过高 ")
+    private Integer warningType;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+}

+ 63 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatAttendance.java

@@ -0,0 +1,63 @@
+package cn.com.ctop.job.bytedance.entity;
+
+import lombok.Data;
+
+/**
+ * 考勤异常统计数据
+ *
+ * @ClassName WechatAttendance
+ * @Author ZHAOXA
+ * @date 2020-09-24 21:00
+ */
+@Data
+public class WechatAttendance {
+    /**
+     * 员工Id
+     */
+    private String userId;
+    /**
+     * 员工名
+     */
+    private String userName;
+    /**
+     * 部门名
+     */
+    private String departName;
+    /**
+     * 审批状态 1-审批中;2-已通过;
+     */
+    private String status;
+    /**
+     * 部门编号
+     */
+    private String departId;
+    /**
+     * 签到日期
+     */
+    private String checkinDate;
+    /**
+     * 打卡类型
+     */
+    private String checkinType;
+    /**
+     * 异常打卡状态
+     */
+    private String exceptionType;
+    /**
+     * 考勤时间
+     */
+    private String checkinTime;
+    /**
+     * 异常考勤状态
+     */
+    private String type;
+    /**
+     * 状态时长
+     */
+    private String stateDuration;
+    /**
+     * 加班时长
+     */
+    private String overtime;
+
+}

+ 142 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatCheckinData.java

@@ -0,0 +1,142 @@
+package cn.com.ctop.job.bytedance.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 io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 企业微信用户
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-09-15
+ */
+@Data
+@TableName("ctop_wechat_checkin_data")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_wechat_checkin_data对象", description = "企业微信用户")
+public class WechatCheckinData {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private String id;
+    /**
+     * 部门id
+     */
+    @Excel(name = "部门id", width = 15)
+    @ApiModelProperty(value = "部门id")
+    private String departId;
+    /**
+     * 用户
+     */
+    @Excel(name = "用户", width = 15)
+    @ApiModelProperty(value = "用户")
+    private String userId;
+    /**
+     * 打开规则名称
+     */
+    @Excel(name = "打开规则名称", width = 15)
+    @ApiModelProperty(value = "打开规则名称")
+    private String groupName;
+    /**
+     * 打卡类型
+     */
+    @Excel(name = "打卡类型", width = 15)
+    @ApiModelProperty(value = "打卡类型")
+    private String checkinType;
+    /**
+     * 异常类型
+     */
+    @Excel(name = "异常类型", width = 15)
+    @ApiModelProperty(value = "异常类型")
+    private String exceptionType;
+    /**
+     * 打卡时间
+     */
+    @ApiModelProperty(value = "打卡时间")
+    private Date checkinTime;
+    /**
+     * 打开地点
+     */
+    @Excel(name = "打开地点", width = 15)
+    @ApiModelProperty(value = "打开地点")
+    private String locationTitle;
+    /**
+     * 打开地点详情
+     */
+    @Excel(name = "打开地点详情", width = 15)
+    @ApiModelProperty(value = "打开地点详情")
+    private String locationDetail;
+    /**
+     * 打卡wifi名称
+     */
+    @Excel(name = "打卡wifi名称", width = 15)
+    @ApiModelProperty(value = "打卡wifi名称")
+    private String wifiname;
+    /**
+     * 打卡备注
+     */
+    @Excel(name = "打卡备注", width = 15)
+    @ApiModelProperty(value = "打卡备注")
+    private String notes;
+    /**
+     * 打卡的MAC地址/bssid
+     */
+    @Excel(name = "打卡的MAC地址/bssid", width = 15)
+    @ApiModelProperty(value = "打卡的MAC地址/bssid")
+    private String wifimac;
+    /**
+     * 打卡的附件media_id
+     */
+    @Excel(name = "打卡的附件media_id", width = 15)
+    @ApiModelProperty(value = "打卡的附件media_id")
+    private String mediaids;
+    /**
+     * 位置打卡地点纬度
+     */
+    @Excel(name = "位置打卡地点纬度", width = 15)
+    @ApiModelProperty(value = "位置打卡地点纬度")
+    private String lat;
+    /**
+     * 位置打卡地点经度
+     */
+    @Excel(name = "位置打卡地点经度", width = 15)
+    @ApiModelProperty(value = "位置打卡地点经度")
+    private String lng;
+    /**
+     * 打卡设备id
+     */
+    @Excel(name = "打卡设备id", width = 15)
+    @ApiModelProperty(value = "打卡设备id")
+    private String deviceid;
+
+
+    private Integer overtimeOrNot; // 是否加班
+    private Double overtime; // 加班时长
+    // 数据类型
+    private Integer dataType;
+
+
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 71 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatDepartment.java

@@ -0,0 +1,71 @@
+package cn.com.ctop.job.bytedance.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 io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 部门列表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-09-10
+ */
+@Data
+@TableName("ctop_wechat_department")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_wechat_department对象", description = "部门列表")
+public class WechatDepartment {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 部门名称
+     */
+    @Excel(name = "部门名称", width = 15)
+    @ApiModelProperty(value = "部门名称")
+    private String departName;
+    /**
+     * 部门id
+     */
+    @Excel(name = "部门id", width = 15)
+    @ApiModelProperty(value = "部门id")
+    private String departId;
+    /**
+     * 父部门id
+     */
+    @Excel(name = "父部门id", width = 15)
+    @ApiModelProperty(value = "父部门id")
+    private String parentId;
+    /**
+     * 排序
+     */
+    @Excel(name = "排序", width = 15)
+    @ApiModelProperty(value = "排序")
+    private String departOrder;
+    // 数据类型
+    private Integer dataType;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 66 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatNoList.java

@@ -0,0 +1,66 @@
+package cn.com.ctop.job.bytedance.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 io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 审批信息
+ * @author jeecg-boot
+ * @date   2020-09-23
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_wechat_no_list")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_wechat_no_list对象", description="审批信息")
+public class WechatNoList {
+    
+	/**id*/
+	@TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+	private String id;
+	/**单号*/
+	@Excel(name = "单号", width = 15)
+    @ApiModelProperty(value = "单号")
+	private String spNo;
+	/**单号*/
+	@Excel(name = "1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付", width = 15)
+    @ApiModelProperty(value = "1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付")
+	private String status;
+	/**成员id*/
+	@Excel(name = "成员id", width = 15)
+    @ApiModelProperty(value = "成员id")
+	private String userId;
+	/**type时长*/
+	@Excel(name = "type时长", width = 15)
+    @ApiModelProperty(value = "type时长")
+	private String newDuration;
+	/**1-请假;2-补卡;3-出差;4-外出;5-加班*/
+	@Excel(name = "1-请假;2-补卡;3-出差;4-外出;5-加班", width = 15)
+    @ApiModelProperty(value = "1-请假;2-补卡;3-出差;4-外出;5-加班")
+	private String type;
+	/**开始时间*/
+    @ApiModelProperty(value = "开始时间")
+	private Date newBegin;
+	/**结束时间*/
+    @ApiModelProperty(value = "结束时间")
+	private Date newEnd;
+	// 数据类型
+	private Integer dataType;
+	/**createTime*/
+    @ApiModelProperty(value = "createTime")
+	private Date createTime;
+	/**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+	private Date updateTime;
+}

+ 65 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WechatUserList.java

@@ -0,0 +1,65 @@
+package cn.com.ctop.job.bytedance.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 io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 企业微信用户
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-09-15
+ */
+@Data
+@TableName("ctop_wechat_user_list")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_wechat_user_list对象", description = "企业微信用户")
+public class WechatUserList {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private String id;
+    /**
+     * 成员名称
+     */
+    @Excel(name = "成员名称", width = 15)
+    @ApiModelProperty(value = "成员名称")
+    private String userName;
+    /**
+     * 成员id
+     */
+    @Excel(name = "成员id", width = 15)
+    @ApiModelProperty(value = "成员id")
+    private String userId;
+    /**
+     * 部门id
+     */
+    @Excel(name = "部门id", width = 15)
+    @ApiModelProperty(value = "部门id")
+    private String departId;
+    // 数据类型
+    private Integer dataType;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 86 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/entity/WexinConfig.java

@@ -0,0 +1,86 @@
+package cn.com.ctop.job.bytedance.entity;
+
+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 io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import me.chanjar.weixin.cp.api.WxCpService;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+import java.util.Date;
+
+/**
+ * 企业微信配置信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-06-17
+ */
+@Data
+@TableName("ctop_wexin_config")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_wexin_config对象", description = "企业微信配置信息")
+public class WexinConfig {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.UUID)
+    @ApiModelProperty(value = "id")
+    private Integer id;
+    /**
+     * corpId
+     */
+    @Excel(name = "corpId", width = 15)
+    @ApiModelProperty(value = "corpId")
+    private String corpId;
+    /**
+     * agentId
+     */
+    @Excel(name = "agentId", width = 15)
+    @ApiModelProperty(value = "agentId")
+    private Integer agentId;
+    /**
+     * corpSecret
+     */
+    @Excel(name = "corpSecret", width = 15)
+    @ApiModelProperty(value = "corpSecret")
+    private String corpSecret;
+    /**
+     * aesKey
+     */
+    @Excel(name = "aesKey", width = 15)
+    @ApiModelProperty(value = "aesKey")
+    private String aesKey;
+    /**
+     * token
+     */
+    @Excel(name = "token", width = 15)
+    @ApiModelProperty(value = "token")
+    private String token;
+    /**
+     * remarks
+     */
+    @Excel(name = "remarks", width = 15)
+    @ApiModelProperty(value = "remarks")
+    private String remarks;
+    /**
+     * createTime
+     */
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private WxCpService wxCpService;
+}

+ 166 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/enums/BytedanceConvertType.java

@@ -0,0 +1,166 @@
+package cn.com.ctop.job.bytedance.enums;
+
+public enum BytedanceConvertType {
+    AD_CONVERT_TYPE_PHONE("AD_CONVERT_TYPE_PHONE", 1L, "电话拨打"),
+    AD_CONVERT_TYPE_FORM("AD_CONVERT_TYPE_FORM", 2L, "表单提交"),
+    AD_CONVERT_TYPE_MAP_SEARCH("AD_CONVERT_TYPE_MAP_SEARCH", 3L, "地图搜索"),
+    AD_CONVERT_TYPE_DOWNLOAD_FINISH("AD_CONVERT_TYPE_DOWNLOAD_FINISH", 4L, "下载完成"),
+    AD_CONVERT_TYPE_BUTTON("AD_CONVERT_TYPE_BUTTON", 5L, "按钮跳转"),
+    AD_CONVERT_TYPE_XPATH("AD_CONVERT_TYPE_XPATH", 6L, "xpath类型转换"),
+    AD_CONVERT_TYPE_VIEW("AD_CONVERT_TYPE_VIEW", 7L, "关键页面浏览"),
+    AD_CONVERT_TYPE_ACTIVE("AD_CONVERT_TYPE_ACTIVE", 8L, "激活"),
+    AD_CONVERT_TYPE_DOWNLOAD_START("AD_CONVERT_TYPE_DOWNLOAD_START", 9L, "下载按钮download_start"),
+    AD_CONVERT_TYPE_QQ("AD_CONVERT_TYPE_QQ", 10L, "qq咨询"),
+    AD_CONVERT_TYPE_LOTTERY("AD_CONVERT_TYPE_LOTTERY", 11L, "抽奖"),
+    AD_CONVERT_TYPE_VOTE("AD_CONVERT_TYPE_VOTE", 12L, "投票"),
+    AD_CONVERT_TYPE_ACTIVE_REGISTER("AD_CONVERT_TYPE_ACTIVE_REGISTER", 13L, "激活且注册"),
+    AD_CONVERT_TYPE_PAY("AD_CONVERT_TYPE_PAY", 14L, "激活且付费"),
+    AD_CONVERT_TYPE_INSTALL_FINISH("AD_CONVERT_TYPE_INSTALL_FINISH", 15L, "安装完成"),
+    AD_CONVERT_TYPE_PHONE_CONFIRM("AD_CONVERT_TYPE_PHONE_CONFIRM", 16L, "智能电话-确认拨打"),
+    AD_CONVERT_TYPE_PHONE_CONNECT("AD_CONVERT_TYPE_PHONE_CONNECT", 17L, "智能电话-确认接通"),
+    AD_CONVERT_TYPE_PHONE_EFFECTIVE("AD_CONVERT_TYPE_PHONE_EFFECTIVE", 18L, "智能电话-有效接通"),
+    AD_CONVERT_TYPE_CONSULT_EFFECTIVE("AD_CONVERT_TYPE_CONSULT_EFFECTIVE", 19L, "有效咨询"),
+    AD_CONVERT_TYPE_APP_ORDER("AD_CONVERT_TYPE_APP_ORDER", 20L, "app内下单(电商)"),
+    AD_CONVERT_TYPE_APP_UV("AD_CONVERT_TYPE_APP_UV", 21L, "app内访问"),
+    AD_CONVERT_TYPE_APP_CART("AD_CONVERT_TYPE_APP_CART", 22L, "app内添加购物车(电商)"),
+    AD_CONVERT_TYPE_APP_PAY("AD_CONVERT_TYPE_APP_PAY", 23L, "app内付费"),
+    AD_CONVERT_TYPE_SALES_LEAD("AD_CONVERT_TYPE_SALES_LEAD", 24L, "销售线索"),
+    AD_CONVERT_TYPE_GAME_ADDICTION("AD_CONVERT_TYPE_GAME_ADDICTION", 25L, "关键行为(原深度转化)"),
+    AD_CONVERT_TYPE_CUSTOMER_EFFECTIVE("AD_CONVERT_TYPE_CUSTOMER_EFFECTIVE", 26L, "有效获客"),
+    AD_CONVERT_TYPE_EFFECTIVE_COPY("AD_CONVERT_TYPE_EFFECTIVE_COPY", 27L, "关键页面到达&有效内容复制"),
+    AD_CONVERT_TYPE_COUPON("AD_CONVERT_TYPE_COUPON", 28L, "卡券领取"),
+    AD_CONVERT_TYPE_APP_DETAIL_UV("AD_CONVERT_TYPE_APP_DETAIL_UV", 29L, "app内详情页到站uv"),
+    AD_CONVERT_TYPE_RSS("AD_CONVERT_TYPE_RSS", 30L, "账号关注"),
+    AD_CONVERT_TYPE_FORM_CONNECT("AD_CONVERT_TYPE_FORM_CONNECT", 31L, "表单提交-已接通"),
+    AD_CONVERT_TYPE_FORM_ANSWER("AD_CONVERT_TYPE_FORM_ANSWER", 32L, "有效沟通"),
+    AD_CONVERT_TYPE_DIALBACK("AD_CONVERT_TYPE_DIALBACK", 33L, "提交回呼电话"),
+    AD_CONVERT_TYPE_DIALBACK_CONFIRM("AD_CONVERT_TYPE_DIALBACK_CONFIRM", 34L, "回呼电话-确认拨打"),
+    AD_CONVERT_TYPE_DIALBACK_CONNECT("AD_CONVERT_TYPE_DIALBACK_CONNECT", 35L, "回呼电话-确认接通"),
+    AD_CONVERT_TYPE_FORM_DEEP("AD_CONVERT_TYPE_FORM_DEEP", 36L, "分层表单"),
+    AD_CONVERT_TYPE_UPDATE_LEVEL("AD_CONVERT_TYPE_UPDATE_LEVEL", 37L, "激活且升级"),
+    AD_CONVERT_TYPE_CREATE_GAMEROLE("AD_CONVERT_TYPE_CREATE_GAMEROLE", 38L, "激活且创建角色"),
+    AD_CONVERT_TYPE_NEXT_DAY_OPEN("AD_CONVERT_TYPE_NEXT_DAY_OPEN", 39L, "激活且次留"),
+    AD_CONVERT_TYPE_INVALID_CLUE("AD_CONVERT_TYPE_INVALID_CLUE", 40L, "无效线索"),
+    AD_CONVERT_TYPE_INTENTION_CLUE("AD_CONVERT_TYPE_INTENTION_CLUE", 41L, "有意向客户"),
+    AD_CONVERT_TYPE_HIGH_VALUE_CLUE("AD_CONVERT_TYPE_HIGH_VALUE_CLUE", 42L, "高价值客户"),
+    AD_CONVERT_TYPE_PAID_CLUE("AD_CONVERT_TYPE_PAID_CLUE", 43L, "已成单"),
+    AD_CONVERT_TYPE_NATIVE_ACTION("AD_CONVERT_TYPE_NATIVE_ACTION", 44L, "原生互动"),
+    AD_CONVERT_TYPE_LIKE_ACTION("AD_CONVERT_TYPE_LIKE_ACTION", 45L, "视频点赞"),
+    AD_CONVERT_TYPE_FOLLOW_ACTION("AD_CONVERT_TYPE_FOLLOW_ACTION", 46L, "账户关注"),
+    AD_CONVERT_TYPE_COMMENT_ACTION("AD_CONVERT_TYPE_COMMENT_ACTION", 47L, "视频评论"),
+    AD_CONVERT_TYPE_LOCATION_ACTION("AD_CONVERT_TYPE_LOCATION_ACTION", 48L, "POI点击"),
+    AD_CONVERT_TYPE_SHOPPING_ACTION("AD_CONVERT_TYPE_SHOPPING_ACTION", 49L, "购物车点击"),
+    AD_CONVERT_TYPE_REDIRECT_TO_SHOP("AD_CONVERT_TYPE_REDIRECT_TO_SHOP", 50L, "调起店铺"),
+    AD_CONVERT_TYPE_LINK_ACTION("AD_CONVERT_TYPE_LINK_ACTION", 51L, "link点击"),
+    AD_CONVERT_TYPE_DEEP_PURCHASE("AD_CONVERT_TYPE_DEEP_PURCHASE", 52L, "多次付费"),
+    AD_CONVERT_TYPE_SUCCESSORDER_ACTION("AD_CONVERT_TYPE_SUCCESSORDER_ACTION", 53L, "小店转化"),
+    AD_CONVERT_TYPE_POI_COLLECT("AD_CONVERT_TYPE_POI_COLLECT", 60L, "poi地址点击"),
+    AD_CONVERT_TYPE_POI_ADDRESS_CLICK("AD_CONVERT_TYPE_POI_ADDRESS_CLICK", 61L, "poi收藏"),
+    AD_CONVERT_TYPE_RESERVATION("AD_CONVERT_TYPE_RESERVATION", 62L, "poi预定"),
+    AD_CONVERT_TYPE_MESSAGE_ACTION("AD_CONVERT_TYPE_MESSAGE_ACTION", 63L, "私信消息"),
+    AD_CONVERT_TYPE_SHARE_ACTION("AD_CONVERT_TYPE_SHARE_ACTION", 65L, "分享"),
+    AD_CONVERT_TYPE_CLICK_LANDING_PAGE("AD_CONVERT_TYPE_CLICK_LANDING_PAGE", 66L, "访问推广详情页"),
+    AD_CONVERT_TYPE_CLICK_SHOPWINDOW("AD_CONVERT_TYPE_CLICK_SHOPWINDOW", 67L, "访问主页商品橱窗"),
+    AD_CONVERT_TYPE_CLICK_DOWNLOAD("AD_CONVERT_TYPE_CLICK_DOWNLOAD", 68L, "访问主页下载应用"),
+    AD_CONVERT_TYPE_CLICK_CALL_DY("AD_CONVERT_TYPE_CLICK_CALL_DY", 69L, "点击主页内电话拨打"),
+    AD_CONVERT_TYPE_CLICK_WEBSITE("AD_CONVERT_TYPE_CLICK_WEBSITE", 70L, "访问主页官网"),
+    AD_CONVERT_PAGE_VIEW("AD_CONVERT_PAGE_VIEW", 93L, "访问目标页面"),
+    AD_CONVERT_TYPE_MESSAGE("AD_CONVERT_TYPE_MESSAGE", 94L, "短信"),
+    AD_CONVERT_TYPE_REDIRECT("AD_CONVERT_TYPE_REDIRECT", 95L, "页面跳转"),
+    AD_CONVERT_TYPE_SHOPPING("AD_CONVERT_TYPE_SHOPPING", 96L, "商品购买"),
+    AD_CONVERT_TYPE_CONSULT("AD_CONVERT_TYPE_CONSULT", 97L, "在线咨询"),
+    AD_CONVERT_TYPE_WECHAT("AD_CONVERT_TYPE_WECHAT", 98L, "微信"),
+    AD_CONVERT_TYPE_OTHER("AD_CONVERT_TYPE_OTHER", 99L, "其他"),
+    AD_CONVERT_TYPE_MULTIPLE("AD_CONVERT_TYPE_MULTIPLE", 100L, "多转化事件"),
+    AD_CONVERT_TYPE_POI_MULTIPLE("AD_CONVERT_TYPE_POI_MULTIPLE", 101L, "POI门店多转化目标"),
+    AD_CONVERT_TYPE_MULTI_NATIVE_ACTION("AD_CONVERT_TYPE_MULTI_NATIVE_ACTION", 102L, "互动"),
+    AD_CONVERT_TYPE_LOAN_COMPLETION("AD_CONVERT_TYPE_LOAN_COMPLETION", 103L, "互联网金融-完件"),
+    AD_CONVERT_TYPE_PRE_LOAN_CREDIT("AD_CONVERT_TYPE_PRE_LOAN_CREDIT", 104L, "互联网金融-预授信"),
+    AD_CONVERT_TYPE_LOAN_CREDIT("AD_CONVERT_TYPE_LOAN_CREDIT", 105L, "互联网金融-授信"),
+    AD_CONVERT_TYPE_IDCARD_INFORMATION("AD_CONVERT_TYPE_IDCARD_INFORMATION", 106L, "身份证信息填写完成"),
+    AD_CONVERT_TYPE_BANKCARD_INFORMATION("AD_CONVERT_TYPE_BANKCARD_INFORMATION", 107L, "银行卡信息填写完成"),
+    AD_CONVERT_TYPE_PERSONAL_INFORMATION("AD_CONVERT_TYPE_PERSONAL_INFORMATION", 108L, "补充个人信息填写完成"),
+    AD_CONVERT_TYPE_CERTIFICATION_INFORMATION("AD_CONVERT_TYPE_CERTIFICATION_INFORMATION", 109L, "用户活体认证信息上传完成"),
+    AD_CONVERT_TYPE_LT_ROI("AD_CONVERT_TYPE_LT_ROI", 110L, "广告变现ROI"),
+    AD_CONVERT_TYPE_LIVE_HOMEPAGE("AD_CONVERT_TYPE_LIVE_HOMEPAGE", 111L, "直播导流"),
+    AD_CONVERT_TYPE_REDIRECT_TO_STORE("AD_CONVERT_TYPE_REDIRECT_TO_STORE", 113L, "店铺导流"),
+    AD_CONVERT_TYPE_FEED_LIVE_HOMEPAGE("AD_CONVERT_TYPE_FEED_LIVE_HOMEPAGE", 120L, "火山feed进入直播页"),
+    AD_CONVERT_TYPE_AUTHORIZATION("AD_CONVERT_TYPE_AUTHORIZATION", 121L, "授权(电商)"),
+    AD_CONVERT_TYPE_COMMODITY_CLICK("AD_CONVERT_TYPE_COMMODITY_CLICK", 122L, "快上电商推广目的"),
+    AD_CONVERT_TYPE_CONSULT_CLUE("AD_CONVERT_TYPE_CONSULT_CLUE", 123L, "留咨咨询"),
+    AD_CONVERT_TYPE_BOOST("AD_CONVERT_TYPE_BOOST", 124L, "自然助推"),
+    AD_CONVERT_TYPE_STAY_TIME("AD_CONVERT_TYPE_STAY_TIME", 125L, "店铺停留"),
+    AD_CONVERT_TYPE_PURCHASE_OF_GOODS("AD_CONVERT_TYPE_PURCHASE_OF_GOODS", 156L, "商品签收"),
+    AD_CONVERT_TYPE_PURCHASE_ROI("AD_CONVERT_TYPE_PURCHASE_ROI", 160L, "付费ROI"),
+    AD_CONVERT_TYPE_LIVE_NATIVE_ACITON("AD_CONVERT_TYPE_LIVE_NATIVE_ACITON", 162L, "直播间原生互动"),
+    AD_CONVERT_TYPE_LIVE_FOLLOW_ACITON("AD_CONVERT_TYPE_LIVE_FOLLOW_ACITON", 163L, "直播间关注"),
+    AD_CONVERT_TYPE_LIVE_COMMENT_ACTION("AD_CONVERT_TYPE_LIVE_COMMENT_ACTION", 164L, "直播间评论"),
+    AD_CONVERT_TYPE_LIVE_GIFT_ACTION("AD_CONVERT_TYPE_LIVE_GIFT_ACTION", 165L, "直播间内打赏"),
+    AD_CONVERT_TYPE_LIVE_SLIDECART_CLICK_ACTION("AD_CONVERT_TYPE_LIVE_SLIDECART_CLICK_ACTION", 166L, "直播间查看购物车"),
+    AD_CONVERT_TYPE_LIVE_CLICK_PRODUCT_ACTION("AD_CONVERT_TYPE_LIVE_CLICK_PRODUCT_ACTION", 167L, "直播间查看商品"),
+    AD_CONVERT_TYPE_LIVE_ENTER_ACTION("AD_CONVERT_TYPE_LIVE_ENTER_ACTION", 171L, "直播间观看"),
+    AD_CONVERT_TYPE_LIVE_SUCCESSORDER_ACTION("AD_CONVERT_TYPE_LIVE_SUCCESSORDER_ACTION", 172L, "直播间成单"),
+    AD_CONVERT_TYPE_NOTIFY_DOWNLOAD("AD_CONVERT_TYPE_NOTIFY_DOWNLOAD", 173L, "预约下载"),
+    AD_CONVERT_TYPE_PREMIUM_PAYMENT("AD_CONVERT_TYPE_PREMIUM_PAYMENT", 174L, "保险支付"),
+    AD_CONVERT_TYPE_MESSAGE_CLICK("AD_CONVERT_TYPE_MESSAGE_CLICK", 177L, "私信点击"),
+    AD_CONVERT_TYPE_UG_ROI("AD_CONVERT_TYPE_UG_ROI", 178L, "内广roi"),
+    AD_CONVERT_TYPE_ENTER_HOMEPAGE("AD_CONVERT_TYPE_ENTER_HOMEPAGE", 181L, "进入个人主页"),
+    AD_CONVERT_TYPE_SHOPPING_CART("AD_CONVERT_TYPE_SHOPPING_CART", 182L, "商品购物车点击"),
+    AD_CONVERT_TYPE_WECHAT_REGISTER("AD_CONVERT_TYPE_WECHAT_REGISTER", 183L, "微信内注册"),
+    AD_CONVERT_TYPE_WECHAT_PAY("AD_CONVERT_TYPE_WECHAT_PAY", 184L, "微信内付费"),
+    AD_CONVERT_TYPE_MESSAGE_INTERACTION("AD_CONVERT_TYPE_MESSAGE_INTERACTION", 185L, "沟通互动"),
+    AD_CONVERT_TYPE_LIVE_STAY_TIME("AD_CONVERT_TYPE_LIVE_STAY_TIME", 186L, "直播间停留"),
+    AD_CONVERT_TYPE_NEW_FOLLOW_ACTION("AD_CONVERT_TYPE_NEW_FOLLOW_ACTION", 187L, "粉丝增长"),
+    AD_CONVERT_TYPE_APPLET_CLICK("AD_CONVERT_TYPE_APPLET_CLICK", 189L, "小程序互动"),
+    AD_CONVERT_TYPE_MESSAGE_SERVICE("AD_CONVERT_TYPE_MESSAGE_SERVICE", 190L, "私信服务"),
+    AD_CONVERT_TYPE_MESSAGE_CLUE("AD_CONVERT_TYPE_MESSAGE_CLUE", 192L, "私信留资"),
+    AD_CONVERT_TYPE_LIVE_FANS_ACTION("AD_CONVERT_TYPE_LIVE_FANS_ACTION", 193L, "直播间加入粉丝团"),
+    AD_CONVERT_TYPE_CLUE_CONFIRM("AD_CONVERT_TYPE_CLUE_CONFIRM", 194L, "回访_信息确认"),
+    AD_CONVERT_TYPE_CLUE_INTERFLOW("AD_CONVERT_TYPE_CLUE_INTERFLOW", 195L, "回访_加为好友"),
+    AD_CONVERT_TYPE_CLUE_HIGH_INTENTION("AD_CONVERT_TYPE_CLUE_HIGH_INTENTION", 196L, "回访_高潜成交"),
+    AD_CONVERT_TYPE_LIVE_COMPONENT_CLICK("AD_CONVERT_TYPE_LIVE_COMPONENT_CLICK", 215L, "组件点击");
+
+
+    private String code;
+    private Long num;
+    private String desc;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Long getNum() {
+        return num;
+    }
+
+    public void setNum(Long num) {
+        this.num = num;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    BytedanceConvertType(String code, Long num, String desc) {
+        this.code = code;
+        this.num = num;
+        this.desc = desc;
+    }
+
+    public static Long getNum(String code) {
+        for (BytedanceConvertType convertType : BytedanceConvertType.values()) {
+            if (convertType.getCode().equals(code.trim())) {
+                return convertType.getNum();
+            }
+        }
+        return null;
+    }
+}

+ 71 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/enums/DepartEnum.java

@@ -0,0 +1,71 @@
+package cn.com.ctop.job.bytedance.enums;
+
+
+import cn.com.ctop.job.bytedance.utils.Check;
+
+public enum DepartEnum {
+
+
+    depart1("快手事业部"),
+    depart2("头条事业部"),
+    //    depart3("销售部"),
+    depart4("研发中心部"),
+    //  depart5("内容中心部"),
+    depart6("媒介部"),
+    depart7("渠道部"),
+    depart8("制片部"),
+    depart9("法务部"),
+    depart10("财务部"),
+    depart11("人事行政部"),
+    depart12("快手直播销售部"),
+    depart13("头条直播销售部"),
+    depart14("BD"),
+    depart15("业务管理部"),
+   // depart16("运营部"),
+    depart161("运营一部"),
+    depart162("运营二部"),
+    depart17("聚星事业部"),
+    depart171("视频部"),
+    depart18("销售部");
+//    depart19("销售一部");
+//    depart20("销售二组");
+
+
+    private String departName;
+
+
+    private DepartEnum(String departName) {
+        this.departName = departName;
+
+    }
+
+    public static Boolean getDepart(String departNameStr) {
+        if (Check.isNull(departNameStr)) {
+            return false;
+        }
+        for (DepartEnum departEnum : DepartEnum.values()) {
+            String departName = departEnum.getDepartName();
+
+            if (departNameStr.equals(departName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public String getDepartName() {
+        return departName;
+    }
+
+    public void setDepartName(String departName) {
+        this.departName = departName;
+    }
+
+    @Override
+    public String toString() {
+        return "DepartEnum{" +
+                "departName='" + departName + '\'' +
+                '}';
+    }
+}

+ 51 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AgentManagementJob.java

@@ -0,0 +1,51 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.service.AccountInfoService;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.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.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 头条结算单
+ */
+@Slf4j
+@Component
+public class AgentManagementJob {
+    @Autowired
+    private AccountInfoService accountInfoService;
+    @Autowired
+    private ReportDataService reportDataService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    @XxlJob("agentManagementJob")
+    public void execute() throws Exception {
+        try {
+            List<Long> ids = accountInfoService.getProjectIdsByMediaId("1");
+            String today = DateUtils.date2Str();
+            //昨天
+            String yesterday = DateUtils.getLastDay(today, 1);
+            String yesterday3 = DateUtils.getLastDay(today, 3);
+
+            for (Long id : ids) {
+                executorService.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        reportDataService.insertAccountTransactionDayByProjectId(id, yesterday3, yesterday);
+                    }
+                });
+            }
+            XxlJobHelper.log("同步头条结算单完成");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 39 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AlarmRuleJob.java

@@ -0,0 +1,39 @@
+package cn.com.ctop.job.bytedance.handler;
+
+
+import cn.com.ctop.job.bytedance.entity.RuleAccountTemplate;
+import cn.com.ctop.job.bytedance.service.CommonService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class AlarmRuleJob {
+    @Autowired
+    private CommonService commonService;
+
+    String URLPREFIX = "http://api.tjyourong.com.cn/jeecg-boot/ruleGroup/checkRulesByAccountId?accountId=";
+
+    /**
+     *预警定时任务
+     */
+    @XxlJob("alarmRuleJob")
+    public void execute() throws Exception {
+        try {
+            //查询账户绑定过的规则模板
+            List<RuleAccountTemplate> ruleAccountTemplates = commonService.getRuleAccountTemplateByStatus(0);
+            if (!Check.isNull(ruleAccountTemplates)) {
+                ruleAccountTemplates.forEach(template -> {
+                    String url = URLPREFIX + template.getAccountId();
+                    HttpUtils.httpGet(url, null, null);
+                });
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

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

@@ -0,0 +1,52 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.CommonService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+import cn.com.ctop.job.bytedance.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 TokenService tokenService;
+    @Autowired
+    private CommonService commonService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    /**
+     * 头条时段消耗预警
+     */
+    @XxlJob("byteDanceHourlyAccountWarning")
+    public void execute() throws Exception {
+        try {
+            XxlJobHelper.log("开始时段消耗预警定时任务");
+            long startTime = System.currentTimeMillis();
+            List<CtopOauthToken> tokens = tokenService.getAllBytedanceTokens();
+            if (null == tokens || tokens.isEmpty()) {
+                XxlJobHelper.log("定时获取头条数据异常:未获取到可用的token");
+                XxlJobHelper.handleFail();
+                return;
+            }
+            String statDate = DateUtils.formatDate();
+            String anotherDay = DateUtils.getAnotherDay("yyyy-MM-dd", statDate, 1);
+            tokens.forEach(token -> executorService.submit(() -> commonService.byteDanceAccountWarning(token.getAccountId(), statDate, anotherDay)));
+            XxlJobHelper.log("时段消耗预警定时任务执行完毕,耗时:{} ms", System.currentTimeMillis() - startTime);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 45 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDancePlanRuleDataJob.java

@@ -0,0 +1,45 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.AccountInfoService;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Component
+public class ByteDancePlanRuleDataJob {
+    @Autowired
+    private ReportDataService reportDataService;
+    @Autowired
+    private TokenService tokenService;
+
+    private ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    /**
+     * 规则引擎计划数据任务
+     * @throws Exception
+     */
+    @XxlJob("bytedancePlanRuleLoadJob")
+    public void execute() throws Exception {
+        try {
+            Date date = new Date();
+            List<CtopOauthToken> tokens = tokenService.queryTtValidRuleAccountsToken();
+            tokens.forEach(token -> executorService.submit(()->{
+                //1:删除历史数据
+                reportDataService.deleteRuleData(token.getAccountId());
+                reportDataService.getAdvertiserPlanRuleData(token,date,date, "STAT_TIME_GRANULARITY_DAILY");
+            }));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 38 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceRefreshTokenJob.java

@@ -0,0 +1,38 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.service.TokenService;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ByteDanceRefreshTokenJob {
+
+    @Autowired
+    private TokenService tokenService;
+
+    /**
+     * 刷新token
+     */
+    @XxlJob("byteDanceRefreshTokenJob")
+    public void execute() throws Exception {
+        try {
+            tokenService.refreshBytedanceToken();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 刷新代理商token
+     */
+    @XxlJob("bytedanceRefreshAgentTokenJob")
+    public void bytedanceRefreshAgentTokenJob() throws Exception {
+        try {
+            tokenService.refreshBytedanceAgentToken();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 60 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceAdvertiserDailyReportLoadJob.java

@@ -0,0 +1,60 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+import cn.com.ctop.job.bytedance.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.Date;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * @author 宋英豪
+ * 头条广告主日报数据获取任务
+ * 第二天凌晨跑前一天的数据
+ */
+@Component
+public class BytedanceAdvertiserDailyReportLoadJob {
+    @Autowired
+    private TokenService tokenService;
+    @Autowired
+    private ReportDataService reportService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(3);
+    ;
+
+    /**
+     * 头条广告主日报
+     */
+    @XxlJob("bytedanceAdvertiserDailyReport")
+    public void execute() throws Exception {
+        XxlJobHelper.log("头条广告主日报获取任务执行开始");
+        Date getDate = DateUtils.addDay(new Date(), -1);
+        //1:查询当日数据
+        List<CtopOauthToken> tokens = tokenService.getAllBytedanceTokens();
+        if (null == tokens || tokens.isEmpty()) {
+            XxlJobHelper.log("定时获取头条数据异常:未获取到可用的token");
+            XxlJobHelper.handleFail();
+            return;
+        }
+        CountDownLatch countDownLatch = new CountDownLatch(tokens.size());
+        tokens.forEach(token -> executorService.submit(() -> {
+            try {
+                reportService.getAdvertiserReport(token, getDate, getDate, "STAT_TIME_GRANULARITY_DAILY");
+            } catch (Exception e) {
+                XxlJobHelper.log(e);
+            } finally {
+                countDownLatch.countDown();
+            }
+        }));
+        countDownLatch.await();
+        XxlJobHelper.log("头条广告主日报获取任务执行结束");
+    }
+}

+ 58 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceAdvertiserHourlyReportLoadJob.java

@@ -0,0 +1,58 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+import cn.com.ctop.job.bytedance.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.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * @author 宋英豪
+ */
+@Component
+public class BytedanceAdvertiserHourlyReportLoadJob {
+    @Autowired
+    private TokenService tokenService;
+    @Autowired
+    private ReportDataService reportService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(4);
+
+    /**
+     * 头条广告主时报
+     */
+    @XxlJob("bytedanceAdvertiserHourlyReport")
+    public void execute() throws Exception {
+        try {
+            XxlJobHelper.log("头条时报数据获取开始");
+            Date getDate = new Date();
+            String hour = DateUtils.getNowHour(getDate);
+            //1:查询当日数据
+            List<CtopOauthToken> tokens = tokenService.getAllBytedanceTokens();
+            if (null == tokens || tokens.isEmpty()) {
+                XxlJobHelper.log("定时获取头条小时数据异常:未获取到可用的token");
+                XxlJobHelper.handleFail();
+                return;
+            }
+            tokens.forEach(token -> executorService.submit(() -> {
+                if ("00".equals(hour)) {
+                    Date finalGetDate = DateUtils.addDay(getDate, -1);
+                    //获取广告主信息数据
+                    reportService.getAdvertiserReport(token, finalGetDate, finalGetDate, "STAT_TIME_GRANULARITY_HOURLY");
+                }
+                reportService.getAdvertiserReport(token, getDate, getDate, "STAT_TIME_GRANULARITY_HOURLY");
+            }));
+            XxlJobHelper.log("头条时报数据获取结束");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 42 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedancePlanLoadJob.java

@@ -0,0 +1,42 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+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.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Component
+@Slf4j
+public class BytedancePlanLoadJob {
+    @Autowired
+    private TokenService tokenService;
+    @Autowired
+    private ReportDataService reportDataService;
+    static ExecutorService executorService = Executors.newFixedThreadPool(4);
+
+    /**
+     * 头条全量计划数据
+     *
+     * @throws Exception
+     */
+    @XxlJob("bytedancePlanLoadJob")
+    public void execute() throws Exception {
+        try {
+            //1:查询当日数据
+            log.info("============获取头条全量计划=================");
+            List<CtopOauthToken> tokens = tokenService.getAllBytedanceTokens();
+            tokens.forEach(token -> executorService.submit(() -> reportDataService.getAdvertiserPlan(token, 1, "", null, null)));
+            XxlJobHelper.log("头条全量计划数据获取完成");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 50 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceTodayPlaneLoadJob.java

@@ -0,0 +1,50 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+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.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 头条广告物料数据获取任务
+ *
+ * @author 宋英豪
+ */
+@Component
+public class BytedanceTodayPlaneLoadJob {
+    @Autowired
+    private TokenService tokenService;
+    @Autowired
+    private ReportDataService reportDataService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(6);
+
+    /**
+     * 获取今天头条计划数据
+     */
+    @XxlJob("bytedanceTodayPlaneLoadJob")
+    public void execute() throws Exception {
+        Date getDate = new Date();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        String dateString = dateFormat.format(getDate);
+
+        List<CtopOauthToken> tokens = tokenService.getAllBytedanceTokens();
+        tokens.forEach(token -> executorService.submit(() -> {
+            try {
+                reportDataService.getAdvertiserPlan(token, 1,"", null, dateString);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }));
+        XxlJobHelper.log("当日计划数据同步完成完成");
+    }
+}

+ 26 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/CwjsPolicyApprovedNoticeJob.java

@@ -0,0 +1,26 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CwjsPolicyApprovedNoticeJob {
+
+    /**
+     * 财务结算中 给运营发送微信通知 每月1号 早上9点
+     */
+    @XxlJob("sendMessageToOperate")
+    public void sendMessageToOperate() throws Exception {
+        try {
+//            String url = "http://gateway.tjyourong.com.cn/finance/cwjsPolicyInfo/weiXinNotice";
+            String url = "http://api.tjyourong.com.cn/finance/exportReportController/sendMessageToOperate";
+            HttpUtils.httpGet2(url, null, null);
+            XxlJobHelper.log("send CWJS-operate weixin message success");
+        } catch (Exception e) {
+            XxlJobHelper.log(e.getMessage());
+        }
+    }
+
+}

+ 98 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuiXuanBytedanceJob.java

@@ -0,0 +1,98 @@
+package cn.com.ctop.job.bytedance.handler;
+
+
+import cn.com.ctop.job.bytedance.utils.DateUtils;
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 睿选-头条相关定时
+ */
+@Component
+public class RuiXuanBytedanceJob {
+
+    public final static String URL = "http://ruixuan.api.tjyourong.com.cn/bytedance";
+
+    /**
+     * 新增团长活动列表
+     */
+    @XxlJob("bytedanceColonelActivityJob")
+    public void bytedanceColonelActivityJob() {
+        try {
+            HttpUtils.httpGet(URL + "/addBytedanceColonelActivityList", null, null);
+            XxlJobHelper.log(" --------团长活动列表,执行完成-------- ");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 获取上个月团长订单
+     */
+    @XxlJob("bytedanceInstituteOrderColonel")
+    public void bytedanceInstituteOrderColonel() {
+        try {
+            //获取上个月1号
+            String initMonth = DateUtils.initDateByMonth();
+            String startTime = DateUtils.getMonthBefore("yyyy-MM-dd", initMonth, -1);
+
+            String today = DateUtils.date2Str();
+            //昨天
+//        String yesterday = DateUtils.getLastDay(today, 1);
+            Map<String, Object> paramMap = new HashMap<String, Object>();
+            paramMap.put("startTime", startTime);
+            paramMap.put("endTime", today);
+            HttpUtils.httpGet(URL + "/addBytedanceInstituteOrderColonel", paramMap, null);
+            XxlJobHelper.log(" --------团长订单列表,执行完成 \n-------- 【时间区间】:" + paramMap);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 获取上 上个月 团长订单
+     */
+    @XxlJob("twoMonthsBytedanceOrder")
+    public void twoMonthsBytedanceOrder() {
+        try {
+            //获取上 上个月1号
+            String initMonth = DateUtils.initDateByMonth();
+            String startTime = DateUtils.getMonthBefore("yyyy-MM-dd", initMonth, -2);
+
+
+            String today = DateUtils.date2Str();
+            //昨天
+//        String yesterday = DateUtils.getLastDay(today, 1);
+            Map<String, Object> paramMap = new HashMap<String, Object>();
+            paramMap.put("startTime", startTime);
+            paramMap.put("endTime", today);
+            HttpUtils.httpGet(URL + "/addBytedanceInstituteOrderColonel", paramMap, null);
+            XxlJobHelper.log(" --------团长订单列表,执行完成 \n --------【时间区间】:" + paramMap);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 新增团长订单
+     */
+    @XxlJob("todayBytedanceInstituteOrderColonel")
+    public void todayBytedanceInstituteOrderColonel() {
+        try {
+            String today = DateUtils.date2Str();
+            Map<String, Object> paramMap = new HashMap<String, Object>();
+            paramMap.put("startTime", today);
+            paramMap.put("endTime", today);
+            HttpUtils.httpGet(URL + "/addBytedanceInstituteOrderColonel", paramMap, null);
+            XxlJobHelper.log(" --------团长订单列表,执行完成 \n --------【时间区间】:" + paramMap);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 44 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuleDataAccountCleanJob.java

@@ -0,0 +1,44 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.service.CommonService;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Component
+public class RuleDataAccountCleanJob {
+    @Autowired
+    private TokenService oauthTokenService;
+    @Autowired
+    private ReportDataService reportDataService;
+    private ExecutorService executorService = Executors.newFixedThreadPool(5);
+
+    /**
+     * 规则引擎账户数据
+     *
+     * @throws Exception
+     */
+    @XxlJob("ruleDataAccountCleanJob")
+    public void execute() {
+        try {
+            XxlJobHelper.log("规则预警账户维度数据开始清洗");
+            List<CtopOauthToken> tokens = oauthTokenService.queryTtValidRuleAccountsToken();
+            tokens.forEach(token -> executorService.submit(() -> {
+                reportDataService.deleteRuleAccount(token.getAccountId());
+                reportDataService.cleanRuleDataAccount(token.getAccountId());
+            }));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 40 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/WechatApproveAttendanceJob.java

@@ -0,0 +1,40 @@
+package cn.com.ctop.job.bytedance.handler;
+
+
+import cn.com.ctop.job.bytedance.service.WechatService;
+import cn.com.ctop.job.bytedance.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;
+
+/**
+ * 异常考勤审批数据入库
+ */
+@Component
+public class WechatApproveAttendanceJob {
+    @Autowired
+    private WechatService wechatService;
+
+    /**
+     * 异常考勤审批数据入库
+     * 频率:每月2日凌晨2点同步审批数据 cron:0 0 2 2 * ?
+     * 审批状态表
+     * starttime 统计开始时间,上个月1号零时零分的时间 例:2020-08-01 00:00:00;
+     * endtime 统计结束时间,本月1号零时零分的时间 例:2020-09-01 00:00:00;
+     *
+     * @author ZHAOXA
+     */
+    @XxlJob("wechatApproveAttendanceJob")
+    public void execute() {
+        try {
+            XxlJobHelper.log("--------异常考勤审批数据入库 start ");
+            String initMonth = DateUtils.initDateByMonth();
+            //更新审批状态表e
+            wechatService.getNoListDate(DateUtils.getMonthBefore(DateUtils.NEW_FORMAT, initMonth, -1), initMonth, "0");
+            XxlJobHelper.log("--------异常考勤审批数据入库 end ");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 37 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/WechatAttendanceJob.java

@@ -0,0 +1,37 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.job.bytedance.service.WechatService;
+import cn.com.ctop.job.bytedance.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.Date;
+
+@Component
+public class WechatAttendanceJob {
+    @Autowired
+    private WechatService wechatService;
+
+    /**
+     * 每日考勤和人员数据入库
+     * 员工打卡明细表 每日凌晨2点统计前一天的考勤数据 cron:0 0 2 * * ?
+     * 人员信息表 每日凌晨2点统计前一天的人员数据 cron:0 0 2 * * ?
+     */
+    @XxlJob("wechatAttendanceJob")
+    public void execute() {
+        try {
+            XxlJobHelper.log("--------考勤和人员数据入库 start ");
+            String beforeDay = DateUtils.getLastDay(DateUtils.formatDate(new Date()), 1);
+            //更新人员信息表
+            wechatService.getUserList();
+            XxlJobHelper.log("--------人员数据入库 end ");
+            //更新员工打卡明细表
+            wechatService.getCheckinData(beforeDay + " 00:00:00", beforeDay + " 23:59:59");
+            XxlJobHelper.log("--------考勤数据入库 end ");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 22 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/AccountInfoMapper.java

@@ -0,0 +1,22 @@
+package cn.com.ctop.job.bytedance.mapper;
+
+import cn.com.ctop.job.bytedance.entity.Project;
+import cn.com.ctop.job.bytedance.entity.UserAllocation;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface AccountInfoMapper {
+
+    List<Long> getProjectIdsByMediaId(@Param("mediaId") String mediaId);
+
+    List<String> getAccountIdsByProjectId(@Param("projectId") Long projectId);
+
+    UserAllocation getUserAllocationByAccountId(@Param("accountId") Long accountId);
+
+    Project getProjectById(@Param("projectId") Long projectId);
+
+    List<JSONObject> selectBytaDanceWeiXinIdListByAccountId(@Param("accountId") Long accountId);
+
+}

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

@@ -0,0 +1,16 @@
+package cn.com.ctop.job.bytedance.mapper;
+
+import cn.com.ctop.job.bytedance.entity.RuleAccountTemplate;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public interface CommonMapper {
+
+    List<RuleAccountTemplate> getRuleAccountTemplateByStatus(@Param("status") int status);
+
+    Integer selectMaxHour(@Param("accountId") Long accountId, @Param("statDate") String statDate);
+
+    BigDecimal getCost(@Param("accountId") Long accountId, @Param("statHour") Integer statHour, @Param("statDate") String statDate);
+}

+ 43 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/ReportDataMapper.java

@@ -0,0 +1,43 @@
+package cn.com.ctop.job.bytedance.mapper;
+
+import cn.com.ctop.job.bytedance.entity.ByteDanceAdvertisePlan;
+import cn.com.ctop.job.bytedance.entity.BytedanceAdvertiserDailyReport;
+import cn.com.ctop.job.bytedance.entity.BytedanceAdvertiserHourlyReport;
+import cn.com.ctop.job.bytedance.entity.RuleDataAccount;
+import cn.com.ctop.job.bytedance.entity.RuleDataCreative;
+import cn.com.ctop.job.bytedance.entity.RuleDataPlan;
+import cn.com.ctop.job.bytedance.entity.RuleDataTarget;
+import cn.com.ctop.job.bytedance.entity.TransactionDay;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface ReportDataMapper {
+
+    void replaceBatchAccountTransactionDay(@Param("list") List<TransactionDay> list);
+
+    void replaceBytedanceAdvertiserHourly(BytedanceAdvertiserHourlyReport hourlyReport);
+
+    void replaceBytedanceAdvertiserDaily(BytedanceAdvertiserDailyReport dailyReport);
+
+    void replaceByteDanceAdvertisePlan(ByteDanceAdvertisePlan advertisePlan);
+
+
+    void delRuleDataPlan(@Param("accountId") Long accountId);
+
+    void delRuleDataTarget(@Param("accountId") Long accountId);
+
+    void delRuleDataCreative(@Param("accountId") Long accountId);
+
+    ByteDanceAdvertisePlan getByteDanceAdvertisePlanById(@Param("planId") Long planId);
+
+    void replaceRuleDataTarget(RuleDataTarget target);
+
+    void replaceRuleDataPlan(RuleDataPlan ruleDataPlan);
+
+    void replaceRuleDataCreative(RuleDataCreative dataCreative);
+
+    void delRuleDataAccount(Long accountId);
+
+    void replaceRuleDataAccount(RuleDataAccount ruleDataAccount);
+}

+ 21 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/SendMapper.java

@@ -0,0 +1,21 @@
+package cn.com.ctop.job.bytedance.mapper;
+
+import cn.com.ctop.job.bytedance.entity.WarningOperationLog;
+import cn.com.ctop.job.bytedance.entity.WexinConfig;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SendMapper {
+
+    JSONObject getWChatIdByUserId(@Param("userId") String userId);
+
+    List<WexinConfig> orderByDescList();
+
+    String queryUserIdByAccountId(@Param("accountId") Long accountId);
+
+    void insertWarningOperationLog(WarningOperationLog warningOperationLog);
+
+    List<JSONObject> selectWeiXinIdListByAccountId(@Param("accountId") Long accountId);
+}

+ 25 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/TokenMapper.java

@@ -0,0 +1,25 @@
+package cn.com.ctop.job.bytedance.mapper;
+
+import cn.com.ctop.job.bytedance.entity.BytedanceAgentToken;
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.entity.WechatNoList;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface TokenMapper {
+
+    List<CtopOauthToken> getAllBytedanceTokens();
+
+    List<JSONObject> getAgentTokens();
+
+    CtopOauthToken getOneByAccountId(@Param("accountId") long accountId);
+
+    List<CtopOauthToken> queryTtValidRuleAccountsToken();
+
+    int updateToken(CtopOauthToken oauthToken);
+
+    void replaceAgentToken(@Param("data") BytedanceAgentToken data);
+
+}

+ 34 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/WechatMapper.java

@@ -0,0 +1,34 @@
+package cn.com.ctop.job.bytedance.mapper;
+
+import cn.com.ctop.job.bytedance.entity.WechatAttendance;
+import cn.com.ctop.job.bytedance.entity.WechatCheckinData;
+import cn.com.ctop.job.bytedance.entity.WechatDepartment;
+import cn.com.ctop.job.bytedance.entity.WechatNoList;
+import cn.com.ctop.job.bytedance.entity.WechatUserList;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+public interface WechatMapper {
+
+    void insertWechatNoList(WechatNoList noEntity);
+
+    void deleteWechatDepartment(@Param("name") String name);
+
+    void insertWechatDepartment(WechatDepartment depart);
+
+    List<WechatDepartment> queryWechatDepartmentList(int dataType);
+
+    void insertWechatUserList(WechatUserList userList);
+
+    List<WechatUserList> queryWechatUserList(int type);
+
+    void insertWechatCheckinData(WechatCheckinData checkinData);
+
+    List<WechatAttendance> queryAttendanceData(Map<String, Object> paramsMap);
+
+    WechatCheckinData queryEntityByMap(Map<String, Object> map);
+
+    List<WechatAttendance> queryOverTimeData(Map<String, Object> paramsMap);
+}

+ 56 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/AccountInfoMapper.xml

@@ -0,0 +1,56 @@
+<?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.mapper.AccountInfoMapper">
+
+    <select id="getProjectIdsByMediaId" resultType="Long">
+        SELECT id
+        FROM ctop_project
+        WHERE media_id = #{mediaId}
+    </select>
+
+    <select id="getAccountIdsByProjectId" resultType="String">
+        SELECT account_id
+        FROM ctop_user_allocation
+        WHERE project_id = #{projectId}
+          AND media_id = 1
+    </select>
+
+    <select id="getUserAllocationByAccountId" resultType="cn.com.ctop.job.bytedance.entity.UserAllocation">
+        SELECT *
+        FROM ctop_user_allocation
+        WHERE account_id = #{accountId}
+    </select>
+
+    <select id="getProjectById" resultType="cn.com.ctop.job.bytedance.entity.Project">
+        SELECT *
+        FROM ctop_project
+        WHERE id = #{projectId}
+    </select>
+
+    <select id="selectBytaDanceWeiXinIdListByAccountId" resultType="com.alibaba.fastjson.JSONObject"
+            parameterType="java.lang.Long">
+        select t.*
+        from (
+                 select wexin_id, corp_id
+                 from ctop_corp_wexin_user
+                 where user_id = (select ctop_user_allocation.user_id
+                                  from ctop_user_allocation
+                                  where account_id = #{accountId} limit 1)
+        union all
+        select wexin_id, corp_id
+        from ctop_corp_wexin_user
+        where user_id = (select leader_id
+                         from sys_user
+                         where id = (SELECT ctop_user_allocation.user_id
+                                     FROM ctop_user_allocation
+                                     WHERE account_id = #{accountId}
+            LIMIT 1))
+        union all
+        select wexin_id, corp_id
+        from ctop_corp_wexin_user
+        where user_id = '461857c245f54ba5813bcb5900a23092')  t
+        group by t.wexin_id
+    </select>
+
+
+</mapper>

+ 26 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/CommonMapper.xml

@@ -0,0 +1,26 @@
+<?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.mapper.CommonMapper">
+
+    <select id="getRuleAccountTemplateByStatus" resultType="Long">
+        SELECT *
+        FROM ctop_rule_account_template
+        WHERE template_status = #{status}
+    </select>
+
+    <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>

+ 583 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/ReportDataMapper.xml

@@ -0,0 +1,583 @@
+<?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.mapper.ReportDataMapper">
+
+    <insert id="replaceBatchAccountTransactionDay">
+        REPLACE into ctop_account_transaction_day (advertiser_id,date,balance,cash_cost,cost,frozen,income,reward_cost,
+        shared_wallet_cost,transfer_in,transfer_out,create_time) values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (
+            #{item.advertiserId},
+            #{item.date},
+            #{item.balance},
+            #{item.cashCost},
+            #{item.cost},
+            #{item.frozen},
+            #{item.income},
+            #{item.rewardCost},
+            #{item.sharedWalletCost},
+            #{item.transferIn},
+            #{item.transferOut},
+            NOW()
+            )
+        </foreach>
+    </insert>
+
+    <insert id="replaceBytedanceAdvertiserHourly">
+        REPLACE
+        INTO ctop_bytedance_report_advertiser_hourly (
+            id,
+            advertiser_id,
+            stat_datetime,
+            stat_hour,
+            show_num,
+            click,
+            convert_num,
+            cost,
+            active,
+            download_finish,
+            download_start,
+            click_install,
+            install_finish,
+            register,
+            pay_count,
+            in_app_uv,
+            in_app_detail_uv,
+            in_app_cart,
+            in_app_order,
+            in_app_pay,
+            phone,
+            form,
+            map_search,
+            button,
+            view,
+            qq,
+            lottery,
+            vote,
+            redirect,
+            shopping,
+            consult,
+            wechat,
+            phone_confirm,
+            phone_connect,
+            consult_effective,
+            total_play,
+            valid_play,
+            wifi_play,
+            play_duration_sum,
+            play25_feed_break,
+            play50_feed_break,
+            play75_feed_break,
+            play100_feed_break,
+            advanced_creative_phone_click,
+            advanced_creative_counsel_click,
+            advanced_creative_form_click,
+            share,
+            comment,
+            like_num,
+            follow,
+            home_visited,
+            ies_challenge_click,
+            ies_music_click,
+            interact_per_cost,
+            next_day_open,
+            next_day_open_rate,
+            next_day_open_cost,
+            attribution_next_day_open_cnt,
+            attribution_next_day_open_cost,
+            attribution_next_day_open_rate,
+            create_time,
+            update_time
+            )
+        values (
+        #{id},
+        #{advertiserId},
+        #{statDatetime},
+        #{statHour},
+        #{showNum},
+        #{click},
+        #{convertNum},
+        #{cost},
+        #{active},
+        #{downloadFinish},
+        #{downloadStart},
+        #{clickInstall},
+        #{installFinish},
+        #{register},
+        #{payCount},
+        #{inAppUv},
+        #{inAppDetailUv},
+        #{inAppCart},
+        #{inAppOrder},
+        #{inAppPay},
+        #{phone},
+        #{form},
+        #{mapSearch},
+        #{button},
+        #{VIEW},
+        #{qq},
+        #{lottery},
+        #{vote},
+        #{redirect},
+        #{shopping},
+        #{consult},
+        #{wechat},
+        #{phoneConfirm},
+        #{phoneConnect},
+        #{consultEffective},
+        #{totalPlay},
+        #{validPlay},
+        #{wifiPlay},
+        #{playDurationSum},
+        #{play25FeedBreak},
+        #{play50FeedBreak},
+        #{play75FeedBreak},
+        #{play100FeedBreak},
+        #{advancedCreativePhoneClick},
+        #{advancedCreativeCounselClick},
+        #{advancedCreativeFormClick},
+        #{share},
+        #{comment},
+        #{likeNum},
+        #{follow},
+        #{homeVisited},
+        #{iesChallengeClick},
+        #{iesMusicClick},
+        #{interactPerCost},
+        #{nextDayOpen},
+        #{nextDayOpenRate},
+        #{nextDayOpenCost},
+        #{attributionNextDayOpenCnt},
+        #{attributionNextDayOpenCost},
+        #{attributionNextDayOpenRate},
+        #{createTime},
+        #{updateTime}
+        )
+    </insert>
+
+    <insert id="replaceBytedanceAdvertiserDaily">
+        REPLACE
+        INTO ctop_bytedance_report_advertiser_daily (
+            id,
+            advertiser_id,
+            stat_datetime,
+            show_num,
+            click,
+            convert_num,
+            cost,
+            active,
+            download_finish,
+            download_start,
+            click_install,
+            install_finish,
+            register,
+            pay_count,
+            in_app_uv,
+            in_app_detail_uv,
+            in_app_cart,
+            in_app_order,
+            in_app_pay,
+            phone,
+            form,
+            map_search,
+            button,
+            view,
+            qq,
+            lottery,
+            vote,
+            redirect,
+            shopping,
+            consult,
+            wechat,
+            phone_confirm,
+            phone_connect,
+            consult_effective,
+            total_play,
+            valid_play,
+            wifi_play,
+            play_duration_sum,
+            play25_feed_break,
+            play50_feed_break,
+            play75_feed_break,
+            play100_feed_break,
+            advanced_creative_phone_click,
+            advanced_creative_counsel_click,
+            advanced_creative_form_click,
+            share,
+            comment,
+            like_num,
+            follow,
+            home_visited,
+            ies_challenge_click,
+            ies_music_click,
+            interact_per_cost,
+            next_day_open,
+            next_day_open_rate,
+            next_day_open_cost,
+            attribution_next_day_open_cnt,
+            attribution_next_day_open_cost,
+            attribution_next_day_open_rate,
+            create_time,
+            update_time
+            )
+        values (
+        #{id},
+        #{advertiserId},
+        #{statDatetime},
+        #{showNum},
+        #{click},
+        #{convertNum},
+        #{cost},
+        #{active},
+        #{downloadFinish},
+        #{downloadStart},
+        #{clickInstall},
+        #{installFinish},
+        #{register},
+        #{payCount},
+        #{inAppUv},
+        #{inAppDetailUv},
+        #{inAppCart},
+        #{inAppOrder},
+        #{inAppPay},
+        #{phone},
+        #{form},
+        #{mapSearch},
+        #{button},
+        #{VIEW},
+        #{qq},
+        #{lottery},
+        #{vote},
+        #{redirect},
+        #{shopping},
+        #{consult},
+        #{wechat},
+        #{phoneConfirm},
+        #{phoneConnect},
+        #{consultEffective},
+        #{totalPlay},
+        #{validPlay},
+        #{wifiPlay},
+        #{playDurationSum},
+        #{play25FeedBreak},
+        #{play50FeedBreak},
+        #{play75FeedBreak},
+        #{play100FeedBreak},
+        #{advancedCreativePhoneClick},
+        #{advancedCreativeCounselClick},
+        #{advancedCreativeFormClick},
+        #{share},
+        #{comment},
+        #{likeNum},
+        #{follow},
+        #{homeVisited},
+        #{iesChallengeClick},
+        #{iesMusicClick},
+        #{interactPerCost},
+        #{nextDayOpen},
+        #{nextDayOpenRate},
+        #{nextDayOpenCost},
+        #{attributionNextDayOpenCnt},
+        #{attributionNextDayOpenCost},
+        #{attributionNextDayOpenRate},
+        #{createTime},
+        #{updateTime}
+        )
+    </insert>
+
+    <insert id="replaceByteDanceAdvertisePlan">
+        REPLACE
+        INTO ctop_bytedance_advertise_plan (
+            id,
+            account_id,
+            name,
+            campaign_id,
+            operation,
+            plan_modify_time,
+            delivery_range,
+            union_video_type,
+            deep_bid_type,
+            deep_cpa_bid,
+            ad_modify_time,
+            ad_create_time,
+            budget_mode,
+            budget,
+            toutiao_status,
+            opt_status,
+            start_time,
+            end_time,
+            bid,
+            pricing,
+            schedule_type,
+            schedule_time,
+            flow_control_mode,
+            open_url,
+            download_type,
+            external_url,
+            toutiao_package,
+            app_type,
+            audit_reject_reason,
+            cpa_bid,
+            cpa_skip_first_phrase,
+            convert_id,
+            hide_if_converted,
+            hide_if_exists,
+            audience,
+            modify_time,
+            gender,
+            platform,
+            create_time,
+            update_time,
+            plan_status,
+            converted_time_duration,
+            download_url,
+            luban_roi_goal,
+            roi_goal,
+            inventory_type,
+            audience_package_id,
+            action_track_url
+            )
+        values (
+        #{id},
+        #{accountId},
+        #{name},
+        #{campaignId},
+        #{operation},
+        #{planModifyTime},
+        #{deliveryRange},
+        #{unionVideoType},
+        #{deepBidType},
+        #{deepCpaBid},
+        #{adModifyTime},
+        #{adCreateTime},
+        #{budgetMode},
+        #{budget},
+        #{toutiaoStatus},
+        #{optStatus},
+        #{startTime},
+        #{endTime},
+        #{bid},
+        #{pricing},
+        #{scheduleType},
+        #{scheduleTime},
+        #{flowControlMode},
+        #{openUrl},
+        #{downloadType},
+        #{externalUrl},
+        #{toutiaoPackage},
+        #{appType},
+        #{auditRejectReason},
+        #{cpaBid},
+        #{cpaSkipFirstPhrase},
+        #{convertId},
+        #{hideIfConverted},
+        #{hideIfExists},
+        #{audience},
+        #{modifyTime},
+        #{gender},
+        #{platform},
+        #{createTime},
+        #{updateTime},
+        #{planStatus},
+        #{convertedTimeDuration},
+        #{downloadUrl},
+        #{lubanRoiGoal},
+        #{roiGoal},
+        #{inventoryType},
+        #{audiencePackageId},
+        #{actionTrackUrl}
+        )
+    </insert>
+
+    <delete id="delRuleDataPlan">
+        DELETE
+        FROM ctop_rule_data_plan
+        where account_id = #{accountId}
+    </delete>
+
+    <delete id="delRuleDataTarget">
+        DELETE
+        FROM ctop_rule_data_target
+        where account_id = #{accountId}
+    </delete>
+
+    <delete id="delRuleDataCreative">
+        DELETE
+        FROM ctop_rule_data_creative
+        where account_id = #{accountId}
+    </delete>
+
+    <select id="getByteDanceAdvertisePlanById" resultType="cn.com.ctop.job.bytedance.entity.ByteDanceAdvertisePlan">
+        select *
+        from ctop_bytedance_advertise_plan
+        where id = #{planId}
+    </select>
+
+    <insert id="replaceRuleDataTarget">
+        REPLACE
+        INTO ctop_rule_data_target (
+            id,
+            account_id,
+            plan_id,
+            retargeting_tags_exclude,
+            retargeting_tags_include,
+            hide_if_exists,
+            inventory_type,
+            scene_inventory,
+            district,
+            gender,
+            age,
+            exclude_flow_package,
+            platform,
+            hide_if_converted,
+            deep_bid_type,
+            schedule_time,
+            create_time,
+            update_time,
+            plan_name,
+            account_name,
+            status
+            )
+        values (
+        #{id},
+        #{accountId},
+        #{planId},
+        #{retargetingTagsExclude},
+        #{retargetingTagsInclude},
+        #{hideIfExists},
+        #{inventoryType},
+        #{sceneInventory},
+        #{district},
+        #{gender},
+        #{age},
+        #{excludeFlowPackage},
+        #{platform},
+        #{hideIfConverted},
+        #{deepBidType},
+        #{scheduleTime},
+        #{createTime},
+        #{updateTime},
+        #{planName},
+        #{accountName},
+        #{status}
+        )
+    </insert>
+
+    <insert id="replaceRuleDataPlan">
+        REPLACE
+        INTO ctop_rule_data_plan (
+            id,
+            account_id,
+            account_name,
+            plan_id,
+            plan_name,
+            external_url,
+            download_url,
+            cost,
+            convert_num,
+            convert_cost,
+            next_day_open_rate,
+            pricing,
+            budget,
+            create_time,
+            update_time,
+            next_day_open_cost,
+            next_day_open,
+            status,
+            cpa_bid,
+            deep_cpabid
+            )
+        values (
+        #{id},
+        #{accountId},
+        #{accountName},
+        #{planId},
+        #{planName},
+        #{externalUrl},
+        #{downloadUrl},
+        #{cost},
+        #{convertNum},
+        #{convertCost},
+        #{nextDayOpenRate},
+        #{pricing},
+        #{budget},
+        #{createTime},
+        #{updateTime},
+        #{nextDayOpenCost},
+        #{nextDayOpen},
+        #{status},
+        #{cpaBid},
+        #{deepCpabid}
+        )
+    </insert>
+
+    <insert id="replaceRuleDataCreative">
+        REPLACE
+        INTO ctop_rule_data_creative (
+            id,
+            account_id,
+            plan_id,
+            creative_id,
+            plan_name,
+            presented_video,
+            creative_title,
+            source,
+            create_time,
+            update_time,
+            account_name,
+            status
+            )
+        values (
+        #{id},
+        #{accountId},
+        #{planId},
+        #{creativeId},
+        #{planName},
+        #{presentedVideo},
+        #{creativeTitle},
+        #{source},
+        #{createTime},
+        #{updateTime},
+        #{accountName},
+        #{status}
+        )
+    </insert>
+
+    <delete id="delRuleDataAccount">
+        DELETE
+        FROM ctop_rule_data_account
+        where account_id = #{accountId}
+    </delete>
+
+
+    <insert id="replaceRuleDataAccount">
+        REPLACE
+        INTO ctop_rule_data_account (
+            id,
+            account_id,
+            account_name,
+            cost,
+            valid_balance,
+            convert_num,
+            convert_cost,
+            next_day_open_num,
+            next_day_open_cost,
+            next_day_open_rate,
+            status,
+            )
+        values (
+        #{id},
+        #{accountId},
+        #{accountName},
+        #{cost},
+        #{validBalance},
+        #{convertNum},
+        #{convertCost},
+        #{nextDayOpenNum},
+        #{nextDayOpenCost},
+        #{nextDayOpenRate},
+        #{status},
+        )
+    </insert>
+
+</mapper>

+ 61 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/SendMapper.xml

@@ -0,0 +1,61 @@
+<?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.mapper.SendMapper">
+
+    <select id="getWChatIdByUserId" resultType="com.alibaba.fastjson.JSONObject">
+        select t1.wexin_id, corp_id
+        from ctop_corp_wexin_user t1
+                 left join sys_user t2
+                           on t1.user_id = t2.id
+        where t1.user_id = #{userId}
+          and t2.`status` = 1
+    </select>
+
+    <select id="orderByDescList" resultType="cn.com.ctop.job.bytedance.entity.WexinConfig">
+        select *
+        from ctop_wexin_config
+        order by create_time desc
+    </select>
+
+    <select id="queryUserIdByAccountId" resultType="String">
+        select distinct user_id
+        from ctop_user_allocation
+        where account_id = #{accountId}
+    </select>
+
+
+    <insert id="insertWarningOperationLog">
+        INSERT INTO ctop_warning_operation_log (account_id, unit_id, user_id, subject, warning_type)
+        VALUES (#{accountId},
+                #{unitId},
+                #{userId},
+                #{subject},
+                #{warningType})
+    </insert>
+
+    <select id="selectWeiXinIdListByAccountId" resultType="com.alibaba.fastjson.JSONObject"
+            parameterType="java.lang.Long">
+        select t.*
+        from (
+                 select wexin_id, corp_id
+                 from ctop_corp_wexin_user
+                 where user_id = (select ctop_user_allocation.user_id
+                                  from ctop_user_allocation
+                                  where account_id = #{accountId} limit 1)
+        union all
+        select wexin_id, corp_id
+        from ctop_corp_wexin_user
+        where user_id = (select leader_id
+                         from sys_user
+                         where id = (SELECT ctop_user_allocation.user_id
+                                     FROM ctop_user_allocation
+                                     WHERE account_id = #{accountId}
+            LIMIT 1))
+        union all
+        select wexin_id, corp_id
+        from ctop_corp_wexin_user
+        where user_id = 'f6a6843879c949618e4a859140c8a127')  t
+        group by t.wexin_id
+    </select>
+
+</mapper>

+ 90 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/TokenMapper.xml

@@ -0,0 +1,90 @@
+<?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.mapper.TokenMapper">
+
+    <select id="getAllBytedanceTokens" resultType="cn.com.ctop.job.bytedance.entity.CtopOauthToken">
+        select t1.*
+        from ctop_oauth_token t1
+                 left join 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 account_id
+    </select>
+
+    <select id="getAgentTokens" resultType="com.alibaba.fastjson.JSONObject">
+        select *
+        FROM ctop_bytedance_agent_token
+    </select>
+
+
+    <select id="getOneByAccountId" resultType="cn.com.ctop.job.bytedance.entity.CtopOauthToken">
+        select id
+             , media_id
+             , advertiser_id
+             , account_id
+             , access_token
+             , refresh_token
+             , access_token_expires_in
+             , refresh_token_expires_in
+             , agent_type
+             , app_id
+             , create_time
+             , update_time
+        from ctop_oauth_token
+        where account_id = #{accountId}
+        order by create_time desc limit 1
+    </select>
+
+    <select id="queryTtValidRuleAccountsToken" resultType="cn.com.ctop.job.bytedance.entity.CtopOauthToken">
+        SELECT *
+        FROM ctop_oauth_token
+        WHERE account_id IN
+              (SELECT t2.account_id
+               FROM ctop_rule_template t1
+                        INNER JOIN ctop_rule_account_template t2 ON t1.id = t2.template_id
+               WHERE t1.media_type IN (1, 3)
+                 AND t2.template_status = 0
+               GROUP BY t2.account_id
+              )
+    </select>
+
+    <update id="updateToken">
+        UPDATE
+        ctop_oauth_token
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="accessToken != null">access_token = #{accessToken},</if>
+            <if test="accessTokenExpiresIn != null">access_token_expires_in = #{accessTokenExpiresIn},</if>
+            <if test="refreshToken != null">refresh_token = #{refreshToken},</if>
+            <if test="refreshTokenExpiresIn != null">refresh_token_expires_in = #{refreshTokenExpiresIn},</if>
+        </trim>
+        WHERE account_id = #{accountId}
+    </update>
+
+    <insert id="replaceAgentToken">
+        replace
+        into ctop_bytedance_agent_token(
+        id,
+        agent_id,
+        agent_name,
+        access_token,
+        access_token_expires_in,
+        refresh_token,
+        refresh_token_expires_in,
+        agent_type,
+        app_id )
+        values
+            (
+        #{data.id},
+        #{data.agentId},
+        #{data.agentName},
+        #{data.accessToken},
+        #{data.accessTokenExpiresIn},
+        #{data.refreshToken},
+        #{data.refreshTokenExpiresIn},
+        #{data.agentType},
+        #{data.appId}
+        )
+    </insert>
+
+</mapper>

+ 240 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/mapper/xml/WechatMapper.xml

@@ -0,0 +1,240 @@
+<?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.mapper.WechatMapper">
+
+    <insert id="insertWechatNoList">
+        replace
+        into ctop_wechat_no_list(
+        id,
+        sp_no,
+        user_id,
+        type,
+        new_duration,
+        status,
+        new_begin,
+        new_end
+        )
+        values
+            (
+        #{id},
+        #{spNo},
+        #{userId},
+        #{type},
+        #{newDuration},
+        #{status},
+        #{newBegin},
+        #{newEnd}
+        )
+    </insert>
+
+    <delete id="deleteWechatDepartment">
+        DELETE
+        FROM ctop_wechat_department
+        where depart_name = #{name}
+    </delete>
+
+    <insert id="insertWechatDepartment">
+        replace
+        into ctop_wechat_department(
+        depart_name,
+        depart_id,
+        parent_id,
+        depart_order,
+        create_time,
+        update_time
+        )
+        values
+            (
+        #{departName},
+        #{departId},
+        #{parentId},
+        #{departOrder},
+        #{createTime},
+        #{updateTime}
+        )
+    </insert>
+
+    <select id="queryWechatDepartmentList" resultType="cn.com.ctop.job.bytedance.entity.WechatDepartment">
+        SELECT *
+        FROM ctop_wechat_department
+        where data_type = #{dataType}
+    </select>
+
+
+    <insert id="insertWechatUserList">
+        replace
+        into ctop_wechat_user_list(
+        id,
+        user_name,
+        user_id,
+        depart_id
+        )
+        values
+            (
+        #{id},
+        #{userName},
+        #{userId},
+        #{departId}
+        )
+    </insert>
+
+    <select id="queryWechatUserList" resultType="cn.com.ctop.job.bytedance.entity.WechatUserList">
+        SELECT *
+        FROM ctop_wechat_user_list
+        where data_type = #{dataType}
+    </select>
+
+
+    <insert id="insertWechatCheckinData">
+        replace
+        into ctop_wechat_checkin_data(
+        id,
+        depart_id,
+        user_id,
+        group_name,
+        checkin_type,
+        exception_type,
+        checkin_time,
+        location_title,
+        location_detail,
+        wifiname,
+        notes,
+        wifimac,
+        mediaids,
+        lat,
+        lng,
+        deviceid,
+        overtime,
+        overtime_or_not
+        )
+        values
+            (
+        #{id},
+        #{departId},
+        #{userId},
+        #{groupName},
+        #{checkinType},
+        #{exceptionType},
+        #{checkinTime},
+        #{locationTitle},
+        #{locationDetail},
+        #{wifiname},
+        #{notes},
+        #{wifimac},
+        #{mediaids},
+        #{lat},
+        #{lng},
+        #{deviceid},
+        #{overtime},
+        #{overtimeOrNot}
+        )
+    </insert>
+
+
+    <select id="queryAttendanceData" resultType="cn.com.ctop.job.bytedance.entity.WechatAttendance">
+        SELECT DISTINCT
+        us.user_id AS userId,
+        us.user_name AS userName,
+        dpt.depart_id AS departId,
+        dpt.depart_name AS departName,
+        DATE_FORMAT(ck.checkin_time,'%Y-%m-%d') AS checkinDate,
+        ck.checkin_type AS checkinType,
+        ck.exception_type AS exceptionType,
+        nl.status as status,
+        DATE_FORMAT(ck.checkin_time, '%Y-%m-%d %H:%i:%s') AS checkinTime,
+        case when nl.type !='' THEN nl.type
+        when ck.checkin_type ='上班打卡' AND exception_type ='时间异常' then '迟到'
+        when ck.checkin_type ='下班打卡' AND exception_type ='时间异常' then '早退'
+        end AS type,
+        case when nl.type!=''and nl.type !='补卡' then CONCAT(nl.new_duration,' h')
+        when ck.checkin_type ='上班打卡'and ck.exception_type ='时间异常' then
+        CONCAT(TIMESTAMPDIFF(MINUTE,DATE_FORMAT(CONCAT(DATE_FORMAT(ck.checkin_time,'%Y-%m-%d '),'09:36:00'),'%Y-%m-%d
+        %H:%i:%s'),ck.checkin_time)+1,' min')
+        when ck.checkin_type ='下班打卡'and ck.exception_type ='时间异常' then
+        CONCAT(TIMESTAMPDIFF(MINUTE,ck.checkin_time,DATE_FORMAT(CONCAT(DATE_FORMAT(ck.checkin_time,'%Y-%m-%d
+        '),'19:00:00'),'%Y-%m-%d %H:%i:%s')),' min')
+        end AS stateDuration
+        FROM ctop_wechat_user_list AS us
+        LEFT JOIN ctop_wechat_department AS dpt ON us.depart_id = dpt.depart_id
+        LEFT JOIN ctop_wechat_checkin_data AS ck ON ck.user_id = us.user_id
+        LEFT JOIN ctop_wechat_no_list AS nl ON nl.user_id = us.user_id and
+        nl.new_begin Like CONCAT(DATE_FORMAT(ck.checkin_time,'%Y-%m-%d'),'%')
+        WHERE ck.exception_type!='' and ISNULL(ck.exception_type)= 0
+        and us.data_type = dpt.data_type
+        and us.data_type = 0
+        <if test="userId != null and userId != '' ">
+            and us.user_id = #{userId}
+        </if>
+        <if test="userName != null and userName != '' ">
+            and us.user_Name LIKE CONCAT("%",#{userName},"%")
+        </if>
+        <if test="departId != null and departId != '' ">
+            and dpt.depart_id = #{departId}
+        </if>
+        <if test="departName != null and departName != '' ">
+            and dpt.depart_name LIKE CONCAT("%",#{departName},"%")
+        </if>
+        <if test="startTime != null">
+            and ck.checkin_time &gt;= #{startTime}
+        </if>
+        <if test="stopTime != null ">
+            and ck.checkin_time &lt;= #{stopTime}
+        </if>
+        order by us.depart_id,us.user_name ,ck.checkin_time
+    </select>
+
+    <select id="queryEntityByMap" resultType="cn.com.ctop.job.bytedance.entity.WechatCheckinData">
+        SELECT
+        *
+        FROM ctop_wechat_checkin_data
+        <where>
+            <if test="userId != null and userId != '' ">
+                and user_id = #{userId}
+            </if>
+            <if test="departId != null and departId != '' ">
+                and depart_id = #{departId}
+            </if>
+            <if test="checkinType != null">
+                and checkin_type = #{checkinType}
+            </if>
+            <if test="checkinDate != null ">
+                and checkin_time like concat(#{checkinDate},"%")
+            </if>
+        </where>
+    </select>
+
+    <select id="queryOverTimeData" resultType="cn.com.ctop.job.bytedance.entity.WechatAttendance">
+        SELECT
+        us.user_id AS userId,
+        us.user_name AS userName,
+        dpt.depart_id AS departId,
+        dpt.depart_name AS departName,
+        DATE_FORMAT(ck.checkin_time,'%Y-%m-%d') AS checkinDate,
+        CONCAT(ck.overtime,' h') AS overtime
+        FROM ctop_wechat_checkin_data as ck
+        LEFT JOIN ctop_wechat_user_list as us ON ck.user_id = us.user_id
+        LEFT JOIN ctop_wechat_department as dpt ON dpt.depart_id = us.depart_id
+        WHERE ck.overtime_or_not = 1
+        and us.data_type = dpt.data_type
+        and us.data_type = 0
+        <if test="userId != null and userId != '' ">
+            and us.user_id = #{userId}
+        </if>
+        <if test="userName != null and userName != '' ">
+            and us.user_Name LIKE CONCAT("%",#{userName},"%")
+        </if>
+        <if test="departId != null and departId != '' ">
+            and dpt.depart_id = #{departId}
+        </if>
+        <if test="departName != null and departName != '' ">
+            and dpt.depart_name LIKE CONCAT("%",#{departName},"%")
+        </if>
+        <if test="startTime != null">
+            and ck.checkin_time &gt;= #{startTime}
+        </if>
+        <if test="stopTime != null ">
+            and ck.checkin_time &lt;= #{stopTime}
+        </if>
+        order by us.depart_id,us.user_name ,ck.checkin_time
+    </select>
+</mapper>

+ 15 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/AccountInfoService.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.job.bytedance.service;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.Date;
+import java.util.List;
+
+public interface AccountInfoService {
+
+    List<Long> getProjectIdsByMediaId(String mediaId);
+
+    List<JSONObject> selectBytaDanceWeiXinIdListByAccountId(Long accountId);
+
+}

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

@@ -0,0 +1,12 @@
+package cn.com.ctop.job.bytedance.service;
+
+import cn.com.ctop.job.bytedance.entity.RuleAccountTemplate;
+
+import java.util.List;
+
+public interface CommonService {
+
+    List<RuleAccountTemplate> getRuleAccountTemplateByStatus(int status);
+
+    void byteDanceAccountWarning(Long accountId, String statDate, String anotherDay);
+}

+ 11 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/IMessageTemplate.java

@@ -0,0 +1,11 @@
+package cn.com.ctop.job.bytedance.service;
+
+import java.math.BigDecimal;
+
+public interface IMessageTemplate {
+
+
+    String getYesterdayMessage(Long accountId, String authName, Integer maxHour, BigDecimal nowCost, String projectName, String userName);
+
+    String getOnDayMessage(Long accountId, String authName, Integer maxHour, BigDecimal cost, String projectName, String userName);
+}

+ 18 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/ISendMessageService.java

@@ -0,0 +1,18 @@
+package cn.com.ctop.job.bytedance.service;
+
+
+import cn.com.ctop.job.bytedance.entity.WexinConfig;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public interface ISendMessageService {
+
+    void sendMessage(String id, String text);
+
+    List<WexinConfig> orderByDescList();
+
+    void sendYesterdayMessage(Long accountId, String authName, Integer maxHour, BigDecimal cost, String projectName, String userName);
+
+    void sendOnDayMessage(Long accountId, String authName, Integer maxHour, BigDecimal cost, String projectName, String userName);
+}

+ 23 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/ReportDataService.java

@@ -0,0 +1,23 @@
+package cn.com.ctop.job.bytedance.service;
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+
+import java.util.Date;
+import java.util.Map;
+
+public interface ReportDataService {
+
+    void insertAccountTransactionDayByProjectId(Long id, String yesterday3, String yesterday);
+
+    void getAdvertiserReport(CtopOauthToken token, Date startDate, Date endDate, String statTimeGranularityDaily);
+
+    void getAdvertiserPlan(CtopOauthToken token, int pageNum, String ids, String date, String updateDate);
+
+    void deleteRuleData(Long accountId);
+
+    void getAdvertiserPlanRuleData(CtopOauthToken token, Date date, Date date1, String stat_time_granularity_daily);
+
+    void deleteRuleAccount(Long accountId);
+
+    void cleanRuleDataAccount(Long accountId);
+}

+ 20 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/TokenService.java

@@ -0,0 +1,20 @@
+package cn.com.ctop.job.bytedance.service;
+
+
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+
+import java.util.List;
+
+/**
+ * token信息
+ */
+public interface TokenService {
+
+    List<CtopOauthToken> getAllBytedanceTokens();
+
+    List<CtopOauthToken> queryTtValidRuleAccountsToken();
+
+    void refreshBytedanceToken();
+
+    void refreshBytedanceAgentToken();
+}

+ 19 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/WechatService.java

@@ -0,0 +1,19 @@
+package cn.com.ctop.job.bytedance.service;
+
+import cn.com.ctop.job.bytedance.entity.WechatAttendance;
+
+import java.util.List;
+import java.util.Map;
+
+public interface WechatService {
+
+    void getNoListDate(String starttime, String endtime,String dataType);
+
+    void getUserList();
+
+    void getCheckinData(String s, String s1);
+
+    List<WechatAttendance> queryAttendanceData(Map<String, Object> paramsMap);
+
+    List<WechatAttendance> queryOverTimeData(Map<String, Object> paramsMap);
+}

+ 32 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/AccountInfoServiceImpl.java

@@ -0,0 +1,32 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.mapper.AccountInfoMapper;
+import cn.com.ctop.job.bytedance.mapper.ReportDataMapper;
+import cn.com.ctop.job.bytedance.service.AccountInfoService;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class AccountInfoServiceImpl implements AccountInfoService {
+    @Autowired
+    private AccountInfoMapper accountInfoMapper;
+
+    @Autowired
+    private ReportDataMapper userMapper;
+
+    @Override
+    public List<Long> getProjectIdsByMediaId(String mediaId) {
+        return accountInfoMapper.getProjectIdsByMediaId(mediaId);
+    }
+
+    @Override
+    public List<JSONObject> selectBytaDanceWeiXinIdListByAccountId(Long accountId) {
+        return accountInfoMapper.selectBytaDanceWeiXinIdListByAccountId(accountId);
+    }
+
+}

+ 88 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/CommonServiceImpl.java

@@ -0,0 +1,88 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.entity.Project;
+import cn.com.ctop.job.bytedance.entity.RuleAccountTemplate;
+import cn.com.ctop.job.bytedance.entity.UserAllocation;
+import cn.com.ctop.job.bytedance.mapper.AccountInfoMapper;
+import cn.com.ctop.job.bytedance.mapper.CommonMapper;
+import cn.com.ctop.job.bytedance.service.CommonService;
+import cn.com.ctop.job.bytedance.service.ISendMessageService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+@Slf4j
+@Service
+public class CommonServiceImpl implements CommonService {
+    @Autowired
+    private CommonMapper commonMapper;
+
+    @Autowired
+    private AccountInfoMapper accountInfoMapper;
+
+    @Autowired
+    private ISendMessageService sendMessage;
+
+    @Override
+    public List<RuleAccountTemplate> getRuleAccountTemplateByStatus(int status) {
+        return commonMapper.getRuleAccountTemplateByStatus(status);
+    }
+
+    /**
+     * 头条账户 出价预警
+     *
+     * @param accountId
+     */
+    @Override
+    public void byteDanceAccountWarning(Long accountId, String statDate, String anotherDay) {
+        try {
+            Integer maxHour = commonMapper.selectMaxHour(accountId, statDate);
+            if (Check.isNull(maxHour)) {
+                return;
+            }
+            UserAllocation userAllocation = accountInfoMapper.getUserAllocationByAccountId(accountId);
+            if (Check.isNull(userAllocation)) {
+                return;
+            }
+            Project project = accountInfoMapper.getProjectById(userAllocation.getProjectId());
+            if (userAllocation.getAccountStatus() == 1) {
+                return;
+            }
+            BigDecimal warningAmount = userAllocation.getWarningAmount();
+            BigDecimal warningProportion = userAllocation.getWarningProportion();
+            BigDecimal nowCost = commonMapper.getCost(accountId, maxHour, statDate);
+            BigDecimal cost = nowCost.setScale(2, RoundingMode.HALF_UP);
+            if (maxHour != 0) {
+                if (!Check.isNull(nowCost) && nowCost.compareTo(new BigDecimal(0)) != 0) {
+                    BigDecimal lastHourCost = commonMapper.getCost(accountId, maxHour - 1, statDate);
+                    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.sendOnDayMessage(accountId, userAllocation.getAuthName(), maxHour, cost, project.getProjectName(), userAllocation.getUserName());
+                        }
+                    }
+                }
+            }
+
+            if (!Check.isNull(nowCost) && nowCost.compareTo(new BigDecimal(0)) != 0) {
+                BigDecimal yesterdayHourCost = commonMapper.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) {
+                        sendMessage.sendYesterdayMessage(accountId, userAllocation.getAuthName(), maxHour, cost, project.getProjectName(), userAllocation.getUserName());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 36 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/MessageTemplateImpl.java

@@ -0,0 +1,36 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.service.IMessageTemplate;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+@Service
+public class MessageTemplateImpl implements IMessageTemplate {
+
+    @Override
+    public String getYesterdayMessage(Long accountId, String authName, Integer maxHour, BigDecimal nowCost , 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("请您及时查看!");
+        return text.toString();
+    }
+
+    @Override
+    public String getOnDayMessage(Long accountId, String authName, Integer hour, BigDecimal nowCost , 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("消耗金额为:" + nowCost).append("<br/>")
+                .append("请您及时查看!");
+        return text.toString();
+    }
+}

+ 939 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/ReportDataServiceImpl.java

@@ -0,0 +1,939 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.entity.ByteDanceAdvertisePlan;
+import cn.com.ctop.job.bytedance.entity.ByteDanceAdvertiserReportDTO;
+import cn.com.ctop.job.bytedance.entity.BytedanceAdvertiserDailyReport;
+import cn.com.ctop.job.bytedance.entity.BytedanceAdvertiserHourlyReport;
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.entity.RuleDataAccount;
+import cn.com.ctop.job.bytedance.entity.RuleDataCreative;
+import cn.com.ctop.job.bytedance.entity.RuleDataPlan;
+import cn.com.ctop.job.bytedance.entity.RuleDataTarget;
+import cn.com.ctop.job.bytedance.entity.TransactionDay;
+import cn.com.ctop.job.bytedance.entity.UserAllocation;
+import cn.com.ctop.job.bytedance.enums.BytedanceConvertType;
+import cn.com.ctop.job.bytedance.mapper.AccountInfoMapper;
+import cn.com.ctop.job.bytedance.mapper.ReportDataMapper;
+import cn.com.ctop.job.bytedance.mapper.TokenMapper;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import cn.com.ctop.job.bytedance.utils.DateUtils;
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import cn.com.ctop.job.bytedance.utils.ResultMapUtils;
+import cn.com.ctop.job.bytedance.utils.StatusCode;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.PropertyNamingStrategy;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import com.xxl.job.core.context.XxlJobHelper;
+import lombok.extern.slf4j.Slf4j;
+import lombok.var;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Service
+public class ReportDataServiceImpl implements ReportDataService {
+    @Autowired
+    private ReportDataMapper reportDataMapper;
+
+    @Autowired
+    private AccountInfoMapper accountMapper;
+
+    @Autowired
+    private TokenMapper tokenMapper;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(3);
+
+    @Override
+    public void insertAccountTransactionDayByProjectId(Long projectId, String startDate, String endDate) {
+        List<String> accountIdList = accountMapper.getAccountIdsByProjectId(projectId);
+        if (!Check.isNull(accountIdList)) {
+            accountIdList.forEach(accountId -> executorService.submit(() -> this.insertAccountTransactionDay(accountId, startDate, endDate, 1)));
+        }
+    }
+
+
+    public void insertAccountTransactionDay(String accountId, String startDate, String endDate, Integer page) {
+        try {
+            JSONObject obj = queryAccountTransactionDay(accountId, page, 1000, startDate, endDate);
+            if (!Check.isNull(obj) && obj.getInteger("code") == 0) {
+                JSONObject data = obj.getJSONObject("data");
+                JSONArray list = data.getJSONArray("list");
+                List<TransactionDay> transactionDays = JSONArray.parseArray(list.toJSONString(), TransactionDay.class);
+                if (!Check.isNull(transactionDays)) {
+                    reportDataMapper.replaceBatchAccountTransactionDay(transactionDays);
+                }
+                JSONObject pageInfo = data.getJSONObject("page_info");
+                Integer totalPage = pageInfo.getInteger("total_page");
+                if (totalPage > page) {
+                    insertAccountTransactionDay(accountId, startDate, endDate, page + 1);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.info("同步失败:{}", e.toString());
+        }
+    }
+
+    /**
+     * 查询账号日流水
+     *
+     * @return
+     * @author zzy
+     * @Param AccountId 账户id       pageNum 当前页    pageSize 每页显示数量
+     * @create: 2021-07-14
+     */
+    public JSONObject queryAccountTransactionDay(String AccountId, int pageNum, int pageSize, String startDate, String endDate) {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");//设置日期格式
+        Calendar ca = Calendar.getInstance();
+        ca.setTime(new Date());
+        ca.add(Calendar.DATE, -1);
+        // 请求参数
+        Map data = new HashMap() {
+            {
+                put("advertiser_id", AccountId);
+                put("start_date", startDate);
+                put("end_date", endDate);
+                put("page", pageNum);
+                put("page_size", pageSize);
+            }
+        };
+        return sendHttpRequest(data, "advertiser/fund/daily_stat/");
+    }
+
+    /**
+     * 根据地址请求巨量殷勤,返回响应结果
+     *
+     * @author zzy
+     * @Param data 请求参数    apiUrl请求路径
+     * @create: 2021-07-14
+     */
+    public JSONObject sendHttpRequest(Map data, String apiUrl) {
+        String access_token = getToken(Long.parseLong(data.get("advertiser_id").toString()));
+        // 构造请求
+        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
+            @Override
+            public String getMethod() {
+                return "GET";
+            }
+        };
+        httpEntity.setHeader("Access-Token", access_token);
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setURI(URI.create("https://ad.oceanengine.com/open_api/2/" + apiUrl));
+            httpEntity.setEntity(new StringEntity(JSONObject.toJSONString(data), ContentType.APPLICATION_JSON));
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuffer result = new StringBuffer();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                client.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 获取token
+     *
+     * @author zzy
+     * @create: 2021-07-14
+     */
+    public String getToken(long accountId) {
+        CtopOauthToken ctopOauthToken = tokenMapper.getOneByAccountId(accountId);
+        if (ctopOauthToken != null) {
+            return ctopOauthToken.getAccessToken();
+        } else {
+            log.info("未查询到Token");
+            return null;
+        }
+
+    }
+
+    @Override
+    public void getAdvertiserReport(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl) {
+        var conditions = getReportDTO(token, startDate, endDate, bytedanceReportTypePl);
+        getAdvertiserReportByPage(token, conditions, 1);
+    }
+
+    private void getAdvertiserReportByPage(CtopOauthToken token, ByteDanceAdvertiserReportDTO conditions, Integer page) {
+        conditions.setPage(page);
+        SerializeConfig config = new SerializeConfig();
+        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
+        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(conditions, config));
+        JSONObject getObject = getAdvertiserStat(token, jsonObject);
+        if (null == getObject) {
+            XxlJobHelper.log("头条广告主数据获取异常");
+            return;
+        }
+        Integer code = getObject.getInteger("code");
+        String message = getObject.getString("message");
+        if (null == code || code != 0) {
+            XxlJobHelper.log("头条广告主数据获取异常:{}", message);
+            return;
+        }
+        JSONArray dataArray = getObject.getJSONObject("data").getJSONArray("list");
+        if (null == dataArray || dataArray.isEmpty()) {
+            return;
+        }
+
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject data = dataArray.getJSONObject(i);
+            if (null != conditions.getTimeGranularity() && conditions.getTimeGranularity().equals("STAT_TIME_GRANULARITY_HOURLY")) {
+                BytedanceAdvertiserHourlyReport hourlyReport = new BytedanceAdvertiserHourlyReport(data);
+                reportDataMapper.replaceBytedanceAdvertiserHourly(hourlyReport);
+            } else {
+                BytedanceAdvertiserDailyReport dailyReport = new BytedanceAdvertiserDailyReport(data);
+                reportDataMapper.replaceBytedanceAdvertiserDaily(dailyReport);
+            }
+        }
+    }
+
+    private ByteDanceAdvertiserReportDTO getReportDTO(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl) {
+        var conditions = new ByteDanceAdvertiserReportDTO();
+        conditions.setAdvertiserId(token.getAccountId());
+        conditions.setStartDate(DateUtils.formatDate(startDate));
+        conditions.setEndDate(DateUtils.formatDate(endDate));
+        conditions.setPageSize(1000);
+        conditions.setTimeGranularity(bytedanceReportTypePl);
+        conditions.setFields(conditions.getFieldsList());
+        return conditions;
+    }
+
+    /**
+     * 获取广告主报表信息
+     *
+     * @param token
+     * @param conditions
+     * @return
+     */
+    public JSONObject getAdvertiserStat(CtopOauthToken token, JSONObject conditions) {
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/report/advertiser/get/";
+        JSONArray groupBy = new JSONArray();
+        groupBy.add("STAT_GROUP_BY_FIELD_ID");
+        groupBy.add("STAT_GROUP_BY_FIELD_STAT_TIME");
+        conditions.put("group_by", groupBy);
+        return HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, conditions);
+    }
+
+    @Override
+    public void getAdvertiserPlan(CtopOauthToken token, int pageNum, String ids, String date, String updateDate) {
+        JSONArray getIds = null;
+        if (null != ids && !"".equals(ids)) {
+            String[] idString = ids.split(",");
+            if (idString.length > 0) {
+                for (int i = 0; i < idString.length; i++) {
+                    Long getId = Long.parseLong(idString[i]);
+                    getIds.add(getId);
+                }
+            }
+        }
+
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/ad/get/";
+        // 请求参数
+        Map<String, Object> filtering = new HashMap<>();
+        if (null != getIds && getIds.size() > 0) {
+            filtering.put("ids", getIds);
+        }
+        if (null != date && !"".equals(date)) {
+            filtering.put("ad_create_time", date);
+        }
+        if (null != updateDate && !"".equals(updateDate)) {
+            filtering.put("ad_modify_time", updateDate);
+        }
+
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", pageNum);
+        param.put("page_size", 100);
+        param.put("filtering", filtering);
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告计划信息接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, String.valueOf(token.getAccountId()));
+            BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
+            if (null != deepCpabid) {
+                advertisePlan.setDeepCpaBid(deepCpabid);
+            }
+            reportDataMapper.replaceByteDanceAdvertisePlan(advertisePlan);
+            //log.info("============保存头条计划=================");
+        }
+        getAdvertiserPlan(token, pageNum + 1, ids, date, updateDate);
+    }
+
+    @Override
+    public void deleteRuleData(Long accountId) {
+        reportDataMapper.delRuleDataPlan(accountId);
+        reportDataMapper.delRuleDataTarget(accountId);
+        reportDataMapper.delRuleDataCreative(accountId);
+    }
+
+    @Override
+    public void getAdvertiserPlanRuleData(CtopOauthToken token, Date startDate, Date endDate, String bytedanceReportTypePl) {
+        var conditions = getReportDTO(token, startDate, endDate, bytedanceReportTypePl);
+        getPlanRuleDataByPage(token, conditions, 1);
+    }
+
+    private void getPlanRuleDataByPage(CtopOauthToken token, ByteDanceAdvertiserReportDTO conditions, int page) {
+        conditions.setPage(page);
+        var config = new SerializeConfig();
+        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
+        var jsonObject = JSONObject.parseObject(JSON.toJSONString(conditions, config));
+
+        JSONObject getObject = getAdStat(token, jsonObject);
+        if (null == getObject) {
+            log.error("广告计划报表数据获取异常=》account:{};message:{}", token.getAccountId(), "返回数据异常");
+            return;
+        }
+        Integer code = getObject.getInteger("code");
+        var message = getObject.getString("message");
+        if (null == code || code != 0) {
+            log.error("广告计划报表数据获取异常=》account:{};message:{}", token.getAccountId(), message);
+            return;
+        }
+        var dataArray = getObject.getJSONObject("data").getJSONArray("list");
+        if (null == dataArray || dataArray.size() <= 0) {
+            return;
+        }
+        UserAllocation allocation = accountMapper.getUserAllocationByAccountId(token.getAccountId());
+        for (var i = 0; i < dataArray.size(); i++) {
+            var data = dataArray.getJSONObject(i);
+            var ruleDataPlan = new RuleDataPlan(data, token.getAccountId());
+            ruleDataPlan.setAccountName(allocation.getAuthName());
+            ByteDanceAdvertisePlan plan = getSinglePlanById(token, ruleDataPlan.getId() + "");
+            if (null != plan) {
+                String status = plan.getToutiaoStatus();
+                String optStatus = plan.getOptStatus();
+                if (null == optStatus || optStatus.equals("AD_STATUS_DISABLE") || optStatus.trim().equals("")) {
+                    continue;
+                }
+                if (null == status || status.trim().equals("") || status.equals("AD_STATUS_DISABLE")
+                        || status.equals("AD_STATUS_DONE") || status.equals("AD_STATUS_AUDIT_DENY") || status.equals("AD_STATUS_BALANCE_EXCEED")
+                        || status.equals("AD_STATUS_CAMPAIGN_DISABLE") || status.equals("AD_STATUS_CAMPAIGN_EXCEED") || status.equals("AD_STATUS_DELETE")) {
+                    continue;
+                }
+                ruleDataPlan.setBudget(plan.getBudget());
+                ruleDataPlan.setDownloadUrl(plan.getDownloadUrl());
+                ruleDataPlan.setExternalUrl(plan.getExternalUrl());
+                ruleDataPlan.setPricing(plan.getPricing());
+                ruleDataPlan.setCpaBid(plan.getCpaBid());
+                ruleDataPlan.setDeepCpabid(plan.getDeepCpaBid());
+                Long convertId = plan.getConvertId();
+                if (null != convertId && convertId != 0) {
+                    ruleDataPlan.setConvertId(plan.getConvertId());
+                    JSONObject convertTargetObject = readAdConvert(token, plan.getConvertId());
+                    if (null != convertTargetObject) {
+                        ruleDataPlan.setConvertId(BytedanceConvertType.getNum(convertTargetObject.getString("convert_type")));
+                        ruleDataPlan.setDeepConvertTarget(convertTargetObject.getString("deep_external_action"));
+                    }
+                }
+                RuleDataTarget target = new RuleDataTarget();
+                JSONObject audienceObject = JSONObject.parseObject(plan.getAudience());
+                target.setAccountId(token.getAccountId());
+                target.setAccountName(allocation.getAuthName());
+                target.setDeepBidType(plan.getDeepBidType());
+                target.setPlanId(ruleDataPlan.getPlanId());
+                target.setId(ruleDataPlan.getPlanId());
+                target.setCreateTime(new Date());
+                target.setUpdateTime(new Date());
+                if (null != audienceObject.getString("retargeting_tags_exclude")) {
+                    target.setRetargetingTagsExclude(audienceObject.getString("retargeting_tags_exclude"));
+                }
+                if (null != audienceObject.getString("retargeting_tags_include")) {
+                    target.setRetargetingTagsExclude(audienceObject.getString("retargeting_tags_include"));
+                }
+                if (null != audienceObject.getString("retargeting_tags_include")) {
+                    target.setRetargetingTagsInclude(audienceObject.getString("retargeting_tags_include"));
+                }
+                target.setHideIfConverted(plan.getHideIfConverted());
+                target.setHideIfExists(plan.getHideIfExists());
+
+                //target.setInventoryType(plan.getInventoryType());
+                if (null != audienceObject.getString("city")) {
+                    target.setDistrict(audienceObject.getString("city"));
+                }
+                if (null != audienceObject.getString("gender")) {
+                    target.setGender(audienceObject.getString("gender"));
+                }
+                if (null != audienceObject.getString("age")) {
+                    target.setAge(audienceObject.getString("age"));
+                }
+                if (null != audienceObject.getString("exclude_flow_package")) {
+                    target.setExcludeFlowPackage(audienceObject.getString("exclude_flow_package"));
+                }
+//		this.flowPackage = audience.getString("flow_package");
+                if (null != audienceObject.getString("platform")) {
+                    target.setPlatform(audienceObject.getString("platform"));
+                }
+                target.setDeepBidType(plan.getDeepBidType());
+                target.setScheduleTime(plan.getScheduleTime());
+
+                reportDataMapper.replaceRuleDataTarget(target);
+                Map<String, Object> creativeDetail = getCreativeDetail(token, plan.getId());
+                if (null != creativeDetail.get("data")) {
+                    JSONObject detail = (JSONObject) creativeDetail.get("data");
+                    formatCreativeData(detail, allocation, ruleDataPlan);
+                }
+            }
+            reportDataMapper.replaceRuleDataPlan(ruleDataPlan);
+        }
+        getPlanRuleDataByPage(token, conditions, page + 1);
+    }
+
+    private void formatCreativeData(JSONObject detail, UserAllocation allocation, RuleDataPlan plan) {
+        //广告来源
+        String source = detail.getString("source");
+        Integer isPresentedVideo = detail.getInteger("isPresentedVideo");
+        JSONArray creatives = detail.getJSONArray("creatives");
+        if (null != creatives && !creatives.isEmpty()) {
+            for (int i = 0; i < creatives.size(); i++) {
+                JSONObject data = creatives.getJSONObject(i);
+                Long creativeId = data.getLong("creative_id");
+                if (null != creativeId) {
+                    String title = data.getString("title");
+                    RuleDataCreative dataCreative = new RuleDataCreative();
+                    dataCreative.setId(creativeId);
+                    dataCreative.setCreativeId(creativeId);
+                    dataCreative.setCreativeTitle(title);
+                    dataCreative.setPlanId(plan.getId());
+                    dataCreative.setPlanName(plan.getPlanName());
+                    dataCreative.setAccountId(allocation.getAccountId());
+                    dataCreative.setAccountName(allocation.getAuthName());
+                    dataCreative.setSource(source);
+                    dataCreative.setPresentedVideo(isPresentedVideo);
+                    dataCreative.setCreateTime(new Date());
+                    dataCreative.setUpdateTime(new Date());
+                    reportDataMapper.replaceRuleDataCreative(dataCreative);
+                }
+            }
+        }
+    }
+
+    /**
+     * 获取广告计划报表信息
+     *
+     * @param token
+     * @param conditions
+     * @return
+     */
+    private JSONObject getAdStat(CtopOauthToken token, JSONObject conditions) {
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/report/ad/get/";
+        JSONArray groupBy = new JSONArray();
+        groupBy.add("STAT_GROUP_BY_FIELD_ID");
+        groupBy.add("STAT_GROUP_BY_FIELD_STAT_TIME");
+
+
+        JSONObject status = new JSONObject();
+        status.put("status", "AD_STATUS_ALL");
+
+
+        conditions.put("filtering", status);
+        conditions.put("group_by", groupBy);
+        return HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, conditions);
+    }
+
+    public ByteDanceAdvertisePlan getSinglePlanById(CtopOauthToken token, String id) {
+        JSONArray getIds = new JSONArray();
+        getIds.add(id);
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/ad/get/";
+        // 请求参数
+        Map<String, Object> filtering = new HashMap<>();
+        filtering.put("ids", getIds);
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", 1);
+        param.put("page_size", 100);
+        param.put("filtering", filtering);
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告计划信息接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return null;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return null;
+        }
+        JSONObject dataObject = data.getJSONObject(0);
+        ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, String.valueOf(token.getAccountId()));
+        BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
+        if (null != deepCpabid) {
+            advertisePlan.setDeepCpaBid(deepCpabid);
+        }
+        return advertisePlan;
+    }
+
+    public JSONObject readAdConvert(CtopOauthToken token, Long convertId) {
+        String url = "https://ad.oceanengine.com/open_api/2/tools/ad_convert/read/";
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("convert_id", convertId);
+        JSONObject result = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, params);
+        Integer code = result.getInteger("code");
+        String message = result.getString("message");
+        if (null == code || code != 0) {
+            log.error("获取转化数据异常=》account:{};convertId:{};message:{}", token.getAccountId(), convertId, message);
+            return null;
+        }
+        return result.getJSONObject("data");
+    }
+
+    public Map<String, Object> getCreativeDetail(CtopOauthToken token, Long planId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        if (null == planId || planId == 0 || null == token) {
+            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_PARAM_ERROR);
+            resultMap.put("data", null);
+            return resultMap;
+        }
+
+        ByteDanceAdvertisePlan plan = reportDataMapper.getByteDanceAdvertisePlanById(planId);
+        if (null == plan || "AD_STATUS_DELETE".equals(plan.getOptStatus())) {
+            ResultMapUtils.setResultMap(resultMap, StatusCode.BYTEDANCE_ACCOUNT_DATA_NOT_EXIST);
+            resultMap.put("data", null);
+            return resultMap;
+        }
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/creative/get/";
+        // 请求参数
+        JSONObject data = new JSONObject();
+        data.put("advertiser_id", token.getAccountId());
+        data.put("ad_id", planId);
+        JSONObject result = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, data);
+        if (null == result) {
+            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_INTERNET_ERROR);
+            resultMap.put("data", null);
+            return resultMap;
+        }
+        Integer code = result.getInteger("code");
+        String message = result.getString("message");
+        if (null == code) {
+            log.info("广告创意获取详情失败,accountId:{},message:{}", token.getAccountId(), message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            result.put("data", null);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        if (code == 40001) {
+            //尚未创建创意
+            resultMap.put("success", true);
+            resultMap.put("code", 0);
+            result.put("data", null);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        if (code != 0) {
+            log.info("广告创意获取详情失败,accountId:{},message:{}", token.getAccountId(), message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            result.put("data", null);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        JSONObject getData = result.getJSONObject("data");
+        resultMap.put("data", formatData(getData));
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS);
+        return resultMap;
+    }
+
+    private JSONObject formatData(JSONObject getData) {
+        JSONObject data = new JSONObject();
+        Long advertiserId = getData.getLong("advertiser_id");
+        if (null != advertiserId && advertiserId != 0) {
+            data.put("advertiserId", advertiserId);
+        }
+        Long adId = getData.getLong("ad_id");
+        if (null != adId && adId != 0) {
+            data.put("adId", adId);
+        }
+        String modifyTime = getData.getString("modify_time");
+        if (null != modifyTime && !"".equals(modifyTime.trim())) {
+            data.put("modifyTime", modifyTime);
+        }
+        String trackUrl = getData.getString("track_url");
+        if (null != trackUrl && !"".equals(trackUrl.trim())) {
+            data.put("trackUrl", trackUrl);
+        }
+        String actionTrackUrl = getData.getString("action_track_url");
+        if (null != actionTrackUrl && !"".equals(actionTrackUrl.trim())) {
+            data.put("actionTrackUrl", actionTrackUrl);
+        }
+        String videoPlayEffectiveTrackUrl = getData.getString("video_play_effective_track_url");
+        if (null != videoPlayEffectiveTrackUrl && !"".equals(videoPlayEffectiveTrackUrl.trim())) {
+            data.put("videoPlayEffectiveTrackUrl", videoPlayEffectiveTrackUrl);
+        }
+        String videoPlayDoneTrackUrl = getData.getString("video_play_done_track_url");
+        if (null != videoPlayDoneTrackUrl && !"".equals(videoPlayDoneTrackUrl.trim())) {
+            data.put("videoPlayDoneTrackUrl", videoPlayDoneTrackUrl);
+        }
+        String videoPlayTrackUrl = getData.getString("video_play_track_url");
+        if (null != videoPlayTrackUrl && !"".equals(videoPlayTrackUrl.trim())) {
+            data.put("videoPlayTrackUrl", videoPlayTrackUrl);
+        }
+        Integer isCommentDisable = getData.getInteger("is_comment_disable");
+        if (null != isCommentDisable) {
+            data.put("isCommentDisable", isCommentDisable);
+        }
+        Integer closeVideoDetail = getData.getInteger("close_video_detail");
+        if (null != closeVideoDetail) {
+            data.put("closeVideoDetail", closeVideoDetail);
+        }
+        String creativeDisplayMode = getData.getString("creative_display_mode");
+        if (null != creativeDisplayMode && !"".equals(creativeDisplayMode.trim())) {
+            data.put("creativeDisplayMode", creativeDisplayMode);
+        }
+        Long smartInventory = getData.getLong("smart_inventory");
+        if (null != smartInventory && smartInventory != 0) {
+            data.put("smartInventory", smartInventory);
+        }
+        String sceneInventory = getData.getString("scene_inventory");
+        if (null != sceneInventory && !"".equals(sceneInventory.trim())) {
+            data.put("sceneInventory", sceneInventory);
+        }
+        Long generateDerivedAd = getData.getLong("generate_derived_ad");
+        if (null != generateDerivedAd && generateDerivedAd != 0) {
+            data.put("generateDerivedAd", generateDerivedAd);
+        }
+        JSONArray inventoryType = getData.getJSONArray("inventory_type");
+        if (null != inventoryType && !inventoryType.isEmpty()) {
+            data.put("inventoryType", inventoryType);
+        }
+        String source = getData.getString("source");
+        if (null != source && !"".equals(source.trim())) {
+            data.put("source", source);
+        }
+        String appName = getData.getString("app_name");
+        if (null != appName && !"".equals(appName.trim())) {
+            data.put("appName", appName);
+        }
+        String webUrl = getData.getString("web_url");
+        if (null != webUrl && !"".equals(webUrl.trim())) {
+            data.put("webUrl", webUrl);
+        }
+        JSONArray adKeywords = getData.getJSONArray("ad_keywords");
+        if (null != adKeywords && !adKeywords.isEmpty()) {
+            data.put("adKeywords", adKeywords);
+        }
+        Long thirdIndustryId = getData.getLong("third_industry_id");
+        if (null != thirdIndustryId && thirdIndustryId != 0) {
+            data.put("thirdIndustryId", thirdIndustryId);
+        }
+        String advancedCreativeType = getData.getString("advanced_creative_type");
+        if (null != advancedCreativeType && !"".equals(advancedCreativeType.trim())) {
+            data.put("advancedCreativeType", advancedCreativeType);
+        }
+        String advancedCreativeTitle = getData.getString("advanced_creative_title");
+        if (null != advancedCreativeTitle && !"".equals(advancedCreativeTitle.trim())) {
+            data.put("advancedCreativeTitle", advancedCreativeTitle);
+        }
+        String phoneNumber = getData.getString("phone_number");
+        if (null != phoneNumber && !"".equals(phoneNumber.trim())) {
+            data.put("phoneNumber", phoneNumber);
+        }
+        String buttonText = getData.getString("button_text");
+        if (null != buttonText && !"".equals(buttonText.trim())) {
+            data.put("buttonText", buttonText);
+        }
+        String actionText = getData.getString("action_text");
+        if (null != actionText && !"".equals(actionText.trim())) {
+            data.put("actionText", actionText);
+        }
+        String formUrl = getData.getString("form_url");
+        if (null != formUrl && !"".equals(formUrl.trim())) {
+            data.put("formUrl", formUrl);
+        }
+        String creativeMaterialMode = getData.getString("creative_material_mode");
+        if (null != creativeMaterialMode && !"".equals(creativeMaterialMode.trim())) {
+            data.put("creativeMaterialMode", creativeMaterialMode);
+        }
+        String iesCoreUserId = getData.getString("ies_core_user_id");
+        if (null != iesCoreUserId && !"".equals(iesCoreUserId.trim())) {
+            data.put("iesCoreUserId", iesCoreUserId);
+        }
+        Long isFeedAndFavSee = getData.getLong("is_feed_and_fav_see");
+        if (null != isFeedAndFavSee) {
+            data.put("isFeedAndFavSee", isFeedAndFavSee);
+        }
+        JSONArray commerceCards = getData.getJSONArray("commerce_cards");
+        if (null != commerceCards && !commerceCards.isEmpty()) {
+            data.put("commerceCards", commerceCards);
+        }
+        String playableUrl = getData.getString("playable_url");
+        if (null != playableUrl && !"".equals(playableUrl.trim())) {
+            data.put("playableUrl", playableUrl);
+        }
+        Long proceduralPackageId = getData.getLong("procedural_package_id");
+        if (null != proceduralPackageId && proceduralPackageId != 0) {
+            data.put("proceduralPackageId", proceduralPackageId);
+        }
+        Long proceduralPackageVersion = getData.getLong("procedural_package_version");
+        if (null != proceduralPackageVersion && proceduralPackageVersion != 0) {
+            data.put("proceduralPackageVersion", proceduralPackageVersion);
+        }
+        Long isPresentedVideo = getData.getLong("is_presented_video");
+        if (null != isPresentedVideo) {
+            data.put("isPresentedVideo", isPresentedVideo);
+        }
+        String subTitle = getData.getString("sub_title");
+        if (null != subTitle && !"".equals(subTitle.trim())) {
+            data.put("subTitle", subTitle);
+        }
+        Long creativeAutoGenerateSwitch = getData.getLong("creative_auto_generate_switch");
+        if (null != creativeAutoGenerateSwitch) {
+            data.put("creativeAutoGenerateSwitch", creativeAutoGenerateSwitch);
+        }
+        String trackUrlSendType = getData.getString("track_url_send_type");
+        if (null != trackUrlSendType && !"".equals(trackUrlSendType.trim())) {
+            data.put("trackUrlSendType", trackUrlSendType);
+        }
+        JSONArray subLinkIdList = getData.getJSONArray("sub_link_id_list");
+        if (null != subLinkIdList && !subLinkIdList.isEmpty()) {
+            data.put("subLinkIdList", subLinkIdList);
+        }
+        JSONArray titleList = getData.getJSONArray("title_list");
+        if (null != titleList && !titleList.isEmpty()) {
+            JSONArray titleArray = new JSONArray();
+            for (int i = 0; i < titleList.size(); i++) {
+                JSONObject title = titleList.getJSONObject(i);
+                JSONArray creativeWordIds = title.getJSONArray("creative_word_ids");
+                JSONArray dpaDictIds = title.getJSONArray("dpa_dict_ids");
+                title.remove("creative_word_ids");
+                title.remove("dpa_dict_ids");
+                title.put("creativeWordIds", creativeWordIds);
+                title.put("dpaDictIds", dpaDictIds);
+                titleArray.add(title);
+            }
+            data.put("titleList", titleArray);
+        }
+        JSONArray imageList = getData.getJSONArray("image_list");
+        if (null != imageList && !imageList.isEmpty()) {
+            JSONArray imageArray = new JSONArray();
+            for (int i = 0; i < imageList.size(); i++) {
+                JSONObject getImage = imageList.getJSONObject(i);
+                JSONObject setImage = new JSONObject();
+                String imageMode = getImage.getString("image_mode");
+                setImage.put("imageMode", imageMode);
+                String imageId = getImage.getString("image_id");
+                if (null != imageId && !"".equals(imageId.trim())) {
+                    setImage.put("imageId", imageId);
+                    if (imageId.contains("web")) {
+                        setImage.put("imageUrl", "https://sf6-ttcdn-tos.pstatp.com/obj/" + imageId);
+                    } else {
+                        setImage.put("imageUrl", "https://sf6-ttcdn-tos.pstatp.com/obj/mosaic-legacy/" + imageId);
+                    }
+                }
+                String videoId = getImage.getString("video_id");
+                if (null != videoId && !"".equals(videoId.trim())) {
+                    setImage.put("videoId", videoId);
+                    setImage.put("videoUrl", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=" + videoId + "&line=0");
+                }
+                JSONArray imageIds = getImage.getJSONArray("image_ids");
+                if (null != imageIds && !imageIds.isEmpty()) {
+                    setImage.put("imageIds", imageIds);
+                }
+                String templateId = getImage.getString("template_id");
+                if (null != templateId && !"".equals(templateId.trim())) {
+                    setImage.put("templateId", templateId);
+                }
+                imageArray.add(setImage);
+            }
+            data.put("imageList", imageArray);
+        }
+        JSONArray creativeList = getData.getJSONArray("creatives");
+        if (null != creativeList && !creativeList.isEmpty()) {
+            JSONArray creativeArray = new JSONArray();
+            for (int i = 0; i < creativeList.size(); i++) {
+                JSONObject getCreative = creativeList.getJSONObject(i);
+                JSONObject setCreative = new JSONObject();
+                String creative_id = getCreative.getString("creative_id");
+                if (null != creative_id && !"".equals(creative_id.trim())) {
+                    setCreative.put("creative_id", creative_id);
+                }
+                String title = getCreative.getString("title");
+                if (null != title && !"".equals(title.trim())) {
+                    setCreative.put("title", title);
+                }
+                JSONArray creativeWordIds = getCreative.getJSONArray("creative_word_ids");
+                if (null != creativeWordIds && !creativeWordIds.isEmpty()) {
+                    setCreative.put("creativeWordIds", creativeWordIds);
+                }
+                JSONArray dpaDictIds = getCreative.getJSONArray("dpa_dict_ids");
+                if (null != dpaDictIds && !dpaDictIds.isEmpty()) {
+                    setCreative.put("dpaDictIds", dpaDictIds);
+                }
+                String imageMode = getCreative.getString("image_mode");
+                if (null != imageMode && !"".equals(imageMode.trim())) {
+                    setCreative.put("imageMode", imageMode);
+                }
+                JSONArray imageIds = getCreative.getJSONArray("imageIds");
+                if (null != imageIds && !imageIds.isEmpty()) {
+                    setCreative.put("imageIds", imageIds);
+                }
+                String imageId = getCreative.getString("image_id");
+                if (null != imageId && !"".equals(imageId.trim())) {
+                    setCreative.put("imageId", imageId);
+                    setCreative.put("imageUrl", "https://sf6-ttcdn-tos.pstatp.com/obj/mosaic-legacy/" + imageId);
+                }
+                String videoId = getCreative.getString("video_id");
+                if (null != videoId && !"".equals(videoId.trim())) {
+                    setCreative.put("videoId", videoId);
+                    setCreative.put("videoUrl", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=" + videoId + "&line=0");
+                }
+                String thirdPartyId = getCreative.getString("third_party_id");
+                if (null != thirdPartyId && !"".equals(thirdPartyId.trim())) {
+                    setCreative.put("thirdPartyId", thirdPartyId);
+                }
+                Long derivePosterCid = getCreative.getLong("derive_poster_cid");
+                if (null != derivePosterCid) {
+                    setCreative.put("derivePosterCid", derivePosterCid);
+                }
+                Integer templateId = getCreative.getInteger("template_id");
+                if (null != templateId) {
+                    setCreative.put("templateId", templateId);
+                }
+                String templateImageId = getCreative.getString("template_image_id");
+                if (null != templateImageId && !"".equals(templateImageId.trim())) {
+                    setCreative.put("templateImageId", templateImageId);
+                }
+                Long dpaTemplate = getCreative.getLong("dpa_template");
+                if (null != dpaTemplate) {
+                    setCreative.put("dpaTemplate", dpaTemplate);
+                }
+                String dpaVideoTemplateType = getCreative.getString("dpa_video_template_type");
+                if (null != dpaVideoTemplateType && !"".equals(dpaVideoTemplateType.trim())) {
+                    setCreative.put("dpaVideoTemplateType", dpaVideoTemplateType);
+                }
+                JSONArray dpaVideoTaskIds = getCreative.getJSONArray("dpa_video_task_ids");
+                if (null != dpaVideoTaskIds && !dpaVideoTaskIds.isEmpty()) {
+                    setCreative.put("dpaVideoTaskIds", dpaVideoTaskIds);
+                }
+                creativeArray.add(setCreative);
+            }
+            data.put("creatives", creativeArray);
+        }
+        return data;
+    }
+
+    @Override
+    public void deleteRuleAccount(Long accountId) {
+        reportDataMapper.delRuleDataAccount(accountId);
+    }
+
+    @Override
+    public void cleanRuleDataAccount(Long accountId) {
+        CtopOauthToken oauthToken = tokenMapper.getOneByAccountId(accountId);
+        //查询账户实时数据
+        JSONObject dataAccount = getAccountReportBy(oauthToken, accountId);
+        if (!dataAccount.isEmpty()) {
+            JSONObject fundData = getAccountFundBy(oauthToken, accountId);
+            RuleDataAccount ruleDataAccount = new RuleDataAccount();
+            ruleDataAccount.setId(accountId);
+            ruleDataAccount.setAccountId(accountId);
+            ruleDataAccount.setAccountName(fundData.getString("name"));
+            ruleDataAccount.setCost(dataAccount.getBigDecimal("cost"));
+            ruleDataAccount.setValidBalance(fundData.getBigDecimal("valid_balance"));
+            ruleDataAccount.setConvertNum(dataAccount.getLong("convert"));
+            ruleDataAccount.setConvertCost(dataAccount.getBigDecimal("convert_cost"));
+            ruleDataAccount.setNextDayOpenNum(dataAccount.getLong("next_day_open"));
+            ruleDataAccount.setNextDayOpenCost(dataAccount.getBigDecimal("next_day_open_cost"));
+            ruleDataAccount.setNextDayOpenRate(dataAccount.getBigDecimal("next_day_open_rate"));
+            reportDataMapper.replaceRuleDataAccount(ruleDataAccount);
+        }
+    }
+
+    public JSONObject getAccountReportBy(CtopOauthToken token, Long advertiserId) {
+        String url = "https://ad.oceanengine.com/open_api/2/report/advertiser/get/";
+
+        JSONObject result = new JSONObject();
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        String now = DateUtils.getNowDate("yyyy-MM-dd");
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", advertiserId);
+        params.put("start_date", now);
+        params.put("end_date", now);
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpGetRequest(url, headers, params));
+        if (jsonObject.getInteger("code") != 0) {
+            XxlJobHelper.log("账户{}获取实时数据失败---{}", advertiserId, jsonObject.getString("message"));
+        } else {
+            result = (JSONObject) jsonObject.getJSONObject("data").getJSONArray("list").get(0);
+        }
+        return result;
+    }
+
+    public JSONObject getAccountFundBy(CtopOauthToken token, Long advertiserId) {
+        String url = "https://ad.oceanengine.com/open_api/2/advertiser/fund/get/";
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", advertiserId);
+
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpGetRequest(url, headers, params));
+        if (jsonObject.getInteger("code") != 0) {
+            XxlJobHelper.log("查询账户余额失败==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            return null;
+        }
+        return jsonObject.getJSONObject("data");
+    }
+
+}

+ 72 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/SendMessageServiceImpl.java

@@ -0,0 +1,72 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.entity.WexinConfig;
+import cn.com.ctop.job.bytedance.mapper.SendMapper;
+import cn.com.ctop.job.bytedance.service.AccountInfoService;
+import cn.com.ctop.job.bytedance.service.CommonService;
+import cn.com.ctop.job.bytedance.service.IMessageTemplate;
+import cn.com.ctop.job.bytedance.service.ISendMessageService;
+import cn.com.ctop.job.bytedance.service.ReportDataService;
+import cn.com.ctop.job.bytedance.service.TokenService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Slf4j
+@Service
+public class SendMessageServiceImpl implements ISendMessageService {
+    @Autowired
+    private SendMapper sendMapper;
+
+    @Autowired
+    private WexinServiceImpl wexinService;
+
+    @Autowired
+    private CommonService commonService;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ReportDataService userService;
+
+    @Autowired
+    private AccountInfoService accountInfoService;
+
+    @Autowired
+    private IMessageTemplate messageTemplate;
+
+    @Override
+    public List<WexinConfig> orderByDescList() {
+        return sendMapper.orderByDescList();
+    }
+
+    @Override
+    public void sendYesterdayMessage(Long accountId, String authName, Integer maxHour, BigDecimal cost, String projectName, String userName) {
+        String txt = messageTemplate.getYesterdayMessage(accountId, authName, maxHour, cost, projectName, userName);
+        List<JSONObject> wexinIds = accountInfoService.selectBytaDanceWeiXinIdListByAccountId(accountId);
+        wexinService.sendMessage(wexinIds, txt);
+
+    }
+
+    @Override
+    public void sendOnDayMessage(Long accountId, String authName, Integer maxHour, BigDecimal cost, String projectName, String userName) {
+        String txt = messageTemplate.getOnDayMessage(accountId, authName, maxHour, cost, projectName, userName);
+        List<JSONObject> wexinIds = accountInfoService.selectBytaDanceWeiXinIdListByAccountId(accountId);
+        wexinService.sendMessage(wexinIds, txt);
+    }
+
+    @Override
+    public void sendMessage(String userId, String text) {
+        JSONObject weChatId = sendMapper.getWChatIdByUserId(userId);
+        if (!Check.isNull(weChatId)) {
+            wexinService.sendMessageByWeChatId(weChatId, text);
+            log.info("消息发送成功,userId:{}", userId);
+        }
+    }
+}

+ 144 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/TokenServiceImpl.java

@@ -0,0 +1,144 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.entity.BytedanceAgentToken;
+import cn.com.ctop.job.bytedance.entity.CtopOauthToken;
+import cn.com.ctop.job.bytedance.mapper.TokenMapper;
+import cn.com.ctop.job.bytedance.service.TokenService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import com.alibaba.fastjson.JSONObject;
+import com.xxl.job.core.context.XxlJobHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class TokenServiceImpl implements TokenService {
+    @Autowired
+    private TokenMapper tokenMapper;
+
+    @Override
+    public List<CtopOauthToken> getAllBytedanceTokens() {
+        return tokenMapper.getAllBytedanceTokens();
+    }
+
+    @Override
+    public List<CtopOauthToken> queryTtValidRuleAccountsToken() {
+        return tokenMapper.queryTtValidRuleAccountsToken();
+    }
+
+    @Override
+    public void refreshBytedanceToken() {
+        List<CtopOauthToken> byteDanceOauthTokens = tokenMapper.getAllBytedanceTokens();
+        if (!Check.isNull(byteDanceOauthTokens)) {
+            for (CtopOauthToken oauthToken : byteDanceOauthTokens) {
+                getByteDanceAccessToken(oauthToken);
+            }
+        }
+    }
+
+    public Map<String, Object> getByteDanceAccessToken(CtopOauthToken token) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String url = "https://ad.oceanengine.com/open_api/oauth2/refresh_token";
+        Map<String, Object> param = new HashMap<>();
+        param.put("app_id", "1635316529903624");
+        param.put("secret", "0c51523e90d6166418fc8421a4896808e90e26f4");
+        param.put("grant_type", "refresh_token");
+        param.put("refresh_token", token.getRefreshToken());
+        String result = HttpUtils.httpPostRequest(url, param, new HashMap<>());
+        System.err.println(JSONObject.parseObject(result));
+        XxlJobHelper.log("头条刷新token;accountId:{},返回信息:{}", token.getAccountId(), result);
+        if (null == result || "".equals(result.trim()) || "null".equalsIgnoreCase(result)) {
+            XxlJobHelper.log("头条刷新token失败;accountId:{},返回信息:{}", token.getAccountId(), result);
+            resultMap.put("message", "token刷新失败");
+            resultMap.put("token", token);
+            resultMap.put("code", 0);
+            return resultMap;
+        }
+        JSONObject resultObject = JSONObject.parseObject(result);
+        Integer code = resultObject.getInteger("code");
+        String message = resultObject.getString("message");
+        if (code == 0) {
+            JSONObject data = resultObject.getJSONObject("data");
+            CtopOauthToken oauthToken = new CtopOauthToken();
+            oauthToken.setAccessToken(data.getString("access_token"));
+            oauthToken.setRefreshToken(data.getString("refresh_token"));
+            Date now = new Date();
+            Integer refreshTokenExpiresIn = data.getInteger("refresh_token_expires_in");
+            Integer expiresIn = data.getInteger("expires_in");
+            oauthToken.setRefreshTokenExpiresIn(addSecond(now, refreshTokenExpiresIn));
+            oauthToken.setAccessTokenExpiresIn(addSecond(now, expiresIn));
+            oauthToken.setAccountId(oauthToken.getAccountId());
+            int i = tokenMapper.updateToken(oauthToken);
+            if (i > 0) {
+                XxlJobHelper.log("头条刷新token成功:accountId:{}", token.getAccountId());
+            }
+            resultMap.put("message", "token刷新成功");
+            resultMap.put("code", 0);
+        } else {
+            XxlJobHelper.log("头条刷新token失败;accountId:{},返回信息:{}", token.getAccountId(), message);
+            resultMap.put("message", message);
+            resultMap.put("token", token);
+            resultMap.put("code", 0);
+        }
+        return resultMap;
+    }
+
+    private Date addSecond(Date date, int seconds) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.SECOND, seconds);
+        return calendar.getTime();
+    }
+
+    @Override
+    public void refreshBytedanceAgentToken() {
+        List<JSONObject> tokens = tokenMapper.getAgentTokens();
+        if (!Check.isNull(tokens)) {
+            for (JSONObject token : tokens) {
+                refreshAgentBytedanceToken(token);
+            }
+        }
+    }
+
+    public void refreshAgentBytedanceToken(JSONObject token) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String url = "https://ad.oceanengine.com/open_api/oauth2/refresh_token";
+        Map<String, Object> param = new HashMap<>();
+        param.put("app_id", "1635316529903624");
+        param.put("secret", "0c51523e90d6166418fc8421a4896808e90e26f4");
+        param.put("grant_type", "refresh_token");
+        param.put("refresh_token", token.getString("refresh_token"));
+        String result = HttpUtils.httpPostRequest(url, param, new HashMap<>());
+        if (!Check.isNull(result)) {
+            JSONObject resultObject = JSONObject.parseObject(result);
+            Integer code = resultObject.getInteger("code");
+            String message = resultObject.getString("message");
+            if (code == 0) {
+                JSONObject data = resultObject.getJSONObject("data");
+                long accessTokenExpireIn = data.getLong("expires_in") * 1000L;
+                long now = System.currentTimeMillis();
+                Date accessTokenExpireInDate = new Date(now + accessTokenExpireIn);
+                data.put("access_token_expires_in", accessTokenExpireInDate);
+                long refreshTokenExpireIn = data.getLong("refresh_token_expires_in") * 1000L;
+                Date refreshTokenExpireInDate = new Date(now + refreshTokenExpireIn);
+                data.put("refresh_token_expires_in", accessTokenExpireInDate);
+                data.put("id", token.getString("id"));
+                data.put("agent_id", token.getString("agent_id"));
+                data.put("agent_name", token.getString("agent_name"));
+                data.put("agent_type", token.getString("agent_type"));
+                data.put("app_id", token.getString("app_id"));
+                BytedanceAgentToken tokenInfo = JSONObject.parseObject(data.toJSONString(), BytedanceAgentToken.class);
+                tokenMapper.replaceAgentToken(tokenInfo);
+            }
+        }
+    }
+
+}

+ 597 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/WechatServiceImpl.java

@@ -0,0 +1,597 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.entity.WechatAttendance;
+import cn.com.ctop.job.bytedance.entity.WechatCheckinData;
+import cn.com.ctop.job.bytedance.entity.WechatDepartment;
+import cn.com.ctop.job.bytedance.entity.WechatNoList;
+import cn.com.ctop.job.bytedance.entity.WechatUserList;
+import cn.com.ctop.job.bytedance.enums.DepartEnum;
+import cn.com.ctop.job.bytedance.mapper.WechatMapper;
+import cn.com.ctop.job.bytedance.service.WechatService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import cn.com.ctop.job.bytedance.utils.DateUtils;
+import cn.com.ctop.job.bytedance.utils.HttpUtils;
+import cn.com.ctop.job.bytedance.utils.QYWxConstant;
+import cn.com.ctop.job.bytedance.utils.SpNoEnum;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Service
+public class WechatServiceImpl implements WechatService {
+
+    @Autowired
+    private WechatMapper wechatMapper;
+
+    @Override
+    public void getNoListDate(String starttime, String endtime, String dataType) {
+        Map<String, Object> returnMap = new HashMap<>();
+        try {
+            long start = DateUtils.timeToStamp(starttime);
+            long end = DateUtils.timeToStamp(endtime);
+            String token = getToken(dataType);
+            Integer page = 0;
+            JSONArray noList = getAllNoList(page, new JSONArray(), start, end, token);
+            boolean sleep = false;
+            if (noList.size() > 600) {
+                sleep = true;
+            }
+            if (!Check.isNull(noList)) {
+                StringBuffer buf = new StringBuffer();
+                //获取审批申请详情 URL;
+                buf.append(QYWxConstant.APP_ROVAL_DETAIL).append("?access_token=").append(token);
+                String userId = null;
+                Map<String, String> parameterMap = null;
+                for (Object spNo : noList) {
+                    parameterMap = new HashMap<>();
+                    //接口频率限制 600次/分钟
+                    if (sleep) {
+                        Thread.sleep(105);
+                    }
+                    JSONObject params = new JSONObject();
+                    params.put("sp_no", spNo);
+                    String resultStr = HttpUtils.httpPostRequestTest(buf.toString(), params.toJSONString(), null);
+                    JSONObject resultJson = JSONObject.parseObject(resultStr);
+                    Integer errcode = resultJson.getInteger("errcode");
+                    if (errcode == 0) {
+                        JSONObject info = resultJson.getJSONObject("info");
+                        String spStatus = info.getString("sp_status");
+                        String spName = info.getString("sp_name");
+                        /**申请单状态:1-审批中;2-已通过,只记录这两种状态数据
+                         * 而且只记录请假、打卡补卡类型
+                         **/
+                        boolean statusisOK = "2".equals(spStatus) || "1".equals(spStatus);
+                        boolean typeisOK = spName.contains("打卡补卡") || spName.contains("请假") || spName.contains("外出") || spName.contains("出差");
+                        if (statusisOK && typeisOK) {
+                            JSONObject applyer = info.getJSONObject("applyer");
+                            if (!Check.isNull(applyer)) {
+                                userId = applyer.getString("userid");
+                            }
+                            //审批申请数据
+                            JSONObject applyData = info.getJSONObject("apply_data");
+                            //获取审批状态数据
+                            getParameterMap(applyData, parameterMap);
+                            WechatNoList noEntity = new WechatNoList();
+                            noEntity.setUserId(userId);
+                            noEntity.setSpNo(spNo.toString());
+                            noEntity.setStatus(spStatus);
+                            if (!Check.isNull(parameterMap.get("newBegin"))) {
+                                noEntity.setNewBegin(DateUtils.stampToTime(Long.valueOf(parameterMap.get("newBegin"))));
+                            }
+                            if (!Check.isNull(parameterMap.get("newEnd"))) {
+                                noEntity.setNewEnd(DateUtils.stampToTime(Long.valueOf(parameterMap.get("newEnd"))));
+                            }
+                            noEntity.setType(parameterMap.get("type"));
+                            noEntity.setNewDuration(parameterMap.get("newDuration"));
+                            if ("1".equals(dataType)) {
+                                noEntity.setDataType(1);
+                            }
+                            UUID uuid = UUID.randomUUID();
+                            noEntity.setId(uuid.toString());
+                            wechatMapper.insertWechatNoList(noEntity);
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            returnMap.put("code", -1);
+            returnMap.put("message", "系统错误");
+            log.error("审批异常", e);
+        }
+    }
+
+    //递归获取审批数据
+    private JSONArray getAllNoList(Integer page, JSONArray spNoList, Long starttime, Long endtime, String token) {
+        JSONObject data = getNoList(page, starttime, endtime, token);
+        spNoList.addAll(data.getJSONArray("sp_no_list"));
+        Integer nextCursor = data.getInteger("next_cursor");
+        if (!Check.isNull(nextCursor)) {
+            return getAllNoList(nextCursor, spNoList, starttime, endtime, token);
+        }
+        return spNoList;
+    }
+
+    /**
+     * 批量获取审批单号,单号!
+     *
+     * @param page      查询起始数,分页查询游标,默认为0
+     * @param starttime 审批单提交的时间范围,开始时间,UNix时间戳
+     * @param endtime   批单提交的时间范围,结束时间,Unix时间戳
+     */
+    private JSONObject getNoList(Integer page, Long starttime, Long endtime, String token) {
+        try {
+            JSONObject params = new JSONObject();
+            params.put("starttime", starttime);
+            params.put("endtime", endtime);
+            params.put("cursor", page);
+            params.put("size", 100);
+            StringBuffer buf = new StringBuffer();
+            //批量获取审批单号 URL
+            buf.append(QYWxConstant.APP_ROVAL_INFO).append("?access_token=").append(token);
+            String resultStr = HttpUtils.httpPostRequestTest(buf.toString(), params.toJSONString(), null);
+            JSONObject resultJson = JSONObject.parseObject(resultStr);
+            Integer errcode = resultJson.getInteger("errcode");
+            if (errcode == 0) {
+                return resultJson;
+            } else {
+                throw new Exception("批量获取审批单号");
+            }
+        } catch (Exception e) {
+            log.error("批量获取审批单号异常", e);
+        }
+        return new JSONObject();
+    }
+
+    private String getToken(String dataType) throws Exception {
+        Map<String, Object> approvaAccessToken = getApprovaAccessToken();
+        if ((Integer) approvaAccessToken.get("code") != 0) {
+            log.error("企业微信获取token失败,返回信息:{}", approvaAccessToken.get("message"));
+            throw new Exception("企业微信获取token失败");
+        }
+        return approvaAccessToken.get("accessToken").toString();
+    }
+
+    public Map<String, Object> getApprovaAccessToken() {
+        Map<String, Object> returnMap = new HashMap<>();
+        try {
+            JSONObject params = new JSONObject();
+            params.put("corpid", QYWxConstant.QYWX_CORP_ID);
+            params.put("corpsecret", QYWxConstant.QYWX_APPROVA_CORP_SECRET);
+            String resultStr = HttpUtils.httpGet(QYWxConstant.QYWX_API_URL + QYWxConstant.QYWX_GET_TOKEN, params, null);
+            JSONObject resultJson = JSONObject.parseObject(resultStr);
+            Integer errcode = resultJson.getInteger("errcode");
+            if (errcode == 0) {
+                returnMap.put("code", 0);
+                returnMap.put("accessToken", resultJson.getString("access_token"));
+            } else {
+                returnMap.put("code", errcode);
+                returnMap.put("message", resultJson.getString("errmsg"));
+            }
+        } catch (Exception e) {
+            returnMap.put("code", -1);
+            returnMap.put("message", "系统错误");
+        }
+        return returnMap;
+    }
+
+    /**
+     * 获取审批状态数据
+     *
+     * @return void
+     * @throws
+     * @author ZHAOXA
+     * @Param [applyData, parameterMap]
+     */
+    private void getParameterMap(JSONObject applyData, Map<String, String> parameterMap) {
+        String control = null;
+        if (!Check.isNull(applyData)) {
+            //审批申请详情,由多个表单控件及其内容组成
+            JSONArray contents = applyData.getJSONArray("contents");
+            if (!Check.isNull(contents)) {
+                for (int i = 0; i < contents.size(); i++) {
+                    //获取content 对象数据
+                    JSONObject contentEntity = contents.getJSONObject(i);
+                    if (!Check.isNull(contentEntity)) {
+                        control = contentEntity.getString("control");
+                        //如果补卡组件为PunchCorrection,直接判断为补卡
+                        if (SpNoEnum.control3.getCode().equals(control)) {
+                            JSONObject value = contentEntity.getJSONObject("value");
+                            if (!Check.isNull(value)) {
+                                JSONObject punch = value.getJSONObject("punch_correction");
+                                if (!Check.isNull(punch)) {
+                                    parameterMap.put("type", SpNoEnum.type2.getName());
+                                    parameterMap.put("newBegin", punch.getString("time"));
+                                    parameterMap.put("newEnd", punch.getString("time"));
+                                }
+                            }
+                            //假勤组件-请假组件 Vacation
+                        } else if (SpNoEnum.control2.getCode().equals(control)) {
+                            JSONObject value = contentEntity.getJSONObject("value");
+                            if (!Check.isNull(value)) {
+                                JSONObject vacation = value.getJSONObject("vacation");
+                                if (!Check.isNull(vacation)) {
+                                    JSONObject selector = vacation.getJSONObject("selector");
+                                    if (!Check.isNull(selector)) {
+                                        getVacation(selector, parameterMap);
+                                    }
+                                    JSONObject attendance = vacation.getJSONObject("attendance");
+                                    if (!Check.isNull(attendance)) {
+                                        getTimeData(attendance, parameterMap);
+                                    }
+                                }
+                            }
+                            //假勤组件-出差/外出/加班组件Attendance
+                        } else if (SpNoEnum.control1.getCode().equals(control)) {
+                            JSONObject value = contentEntity.getJSONObject("value");
+                            if (!Check.isNull(value)) {
+                                JSONObject attendance = value.getJSONObject("attendance");
+                                if (!Check.isNull(attendance)) {
+                                    getTimeData(attendance, parameterMap);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 获取假期类型
+     *
+     * @param
+     * @return void
+     * @throws
+     * @author ZHAOXA
+     */
+    private void getVacation(JSONObject selector, Map<String, String> parameterMap) {
+        JSONArray options = selector.getJSONArray("options");
+        if (!Check.isNull(options)) {
+            for (int j = 0; j < options.size(); j++) {
+                JSONObject option = options.getJSONObject(j);
+                JSONArray values = option.getJSONArray("value");
+                if (!Check.isNull(values)) {
+                    for (int k = 0; k < values.size(); k++) {
+                        JSONObject val = values.getJSONObject(k);
+                        parameterMap.put("type", val.getString("text"));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 获取组件中的假勤类型,假勤开始、结束时间以及时长。
+     *
+     * @return void
+     * @throws
+     * @author ZHAOXA
+     * @Param [attendance, parameterMap]
+     */
+    private void getTimeData(JSONObject attendance, Map<String, String> parameterMap) {
+        String type = attendance.getString("type");
+        //假勤类型,排除类型为1的请假,因为有具体的请假类型,例如:年假,事假等具体类型
+        if (!"1".equals(type)) {
+            parameterMap.put("type", SpNoEnum.getSpNoEnum(type).getName());
+        }
+        JSONObject dateRange = attendance.getJSONObject("date_range");
+        if (!Check.isNull(dateRange)) {
+            parameterMap.put("newBegin", dateRange.getString("new_begin"));
+            parameterMap.put("newEnd", dateRange.getString("new_end"));
+            BigDecimal duration = dateRange.getBigDecimal("new_duration");
+            if (!Check.isNull(duration)) {
+                //除以3600,取小时数
+                BigDecimal second = new BigDecimal(3600);
+                parameterMap.put("newDuration", String.valueOf(duration.divide(second, 1, 4)));
+            }
+        }
+    }
+
+
+    @Override
+    public void getUserList() {
+        try {
+            //获取token
+            Map<String, Object> qywxAccessToken = getQYWXAccessToken();
+            if ((Integer) qywxAccessToken.get("code") != 0) {
+                log.error("企业微信获取token失败,返回信息:{}", qywxAccessToken.get("message"));
+                throw new Exception("企业微信获取token失败");
+            }
+
+            JSONObject params = new JSONObject();
+            params.put("access_token", qywxAccessToken.get("accessToken"));
+
+            // 更新部门
+            getDepartment(params);
+
+            List<WechatDepartment> list = wechatMapper.queryWechatDepartmentList(0);
+            if (Check.isNull(list)) {
+                return;
+            }
+
+            for (WechatDepartment department : list) {
+                String departId = department.getDepartId();
+                params.put("department_id", departId);
+                String resultStr = HttpUtils.httpGet(QYWxConstant.QYWX_USER_SIMPLELIST, params, null);
+                JSONObject resultJson = JSONObject.parseObject(resultStr);
+                Integer errcode = resultJson.getInteger("errcode");
+                if (errcode == 0) {
+                    JSONArray userlist = resultJson.getJSONArray("userlist");
+                    if (!Check.isNull(userlist)) {
+                        for (int i = 0; i < userlist.size(); i++) {
+                            JSONObject userJson = userlist.getJSONObject(i);
+                            if (!Check.isNull(userJson)) {
+                                String userid = userJson.getString("userid");
+                                String id = departId + "_" + userid;
+                                WechatUserList userList = new WechatUserList();
+                                userList.setId(id);
+                                userList.setDepartId(departId);
+                                userList.setUserId(userid);
+                                userList.setUserName(userJson.getString("name"));
+                                wechatMapper.insertWechatUserList(userList);
+                            }
+                        }
+                    }
+                } else {
+                    if (errcode == 60003) {
+                        log.error(department.getDepartName() + ",该部门ID不存在");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void getDepartment(JSONObject params) {
+        try {
+            Map<String, Object> qywxAccessToken = getQYWXAccessToken();
+            if ((Integer) qywxAccessToken.get("code") != 0) {
+                log.error("企业微信获取token失败,返回信息:{}", qywxAccessToken.get("message"));
+                throw new Exception("企业微信获取token失败");
+            }
+            String resultStr = HttpUtils.httpGet(QYWxConstant.QYWX_DEPART_LIST, params, null);
+            JSONObject resultJson = JSONObject.parseObject(resultStr);
+            Integer errcode = resultJson.getInteger("errcode");
+            if (errcode == 0) {
+                JSONArray department = resultJson.getJSONArray("department");
+                if (!Check.isNull(department)) {
+                    for (int i = 0; i < department.size(); i++) {
+                        JSONObject departJson = department.getJSONObject(i);
+                        if (!Check.isNull(departJson)) {
+                            Boolean isTrueOrFalse = DepartEnum.getDepart(departJson.getString("name"));
+                            if (!isTrueOrFalse) {
+                                continue;
+                            }
+                            wechatMapper.deleteWechatDepartment(departJson.getString("name"));
+                            WechatDepartment depart = new WechatDepartment();
+                            depart.setDepartId(departJson.getString("id"));
+                            depart.setDepartName(departJson.getString("name"));
+                            depart.setParentId(departJson.getString("parentid"));
+                            depart.setDepartOrder(departJson.getString("order"));
+                            depart.setCreateTime(new Date());
+                            depart.setUpdateTime(new Date());
+                            wechatMapper.insertWechatDepartment(depart);
+                        }
+                    }
+                }
+            } else {
+                throw new Exception("企业微信获取部门列表");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public Map<String, Object> getQYWXAccessToken() {
+        Map<String, Object> returnMap = new HashMap<>();
+        try {
+            TreeMap<String, Object> params = new TreeMap<>();
+            params.put("corpid", QYWxConstant.QYWX_CORP_ID);
+            params.put("corpsecret", QYWxConstant.QYWX_CORP_SECRET);
+            String resultStr = HttpUtils.httpGet(QYWxConstant.QYWX_API_URL + QYWxConstant.QYWX_GET_TOKEN, params, null);
+            JSONObject resultJson = JSONObject.parseObject(resultStr);
+            Integer errcode = resultJson.getInteger("errcode");
+            if (errcode == 0) {
+                returnMap.put("code", 0);
+                returnMap.put("accessToken", resultJson.getString("access_token"));
+            } else {
+                returnMap.put("code", errcode);
+                returnMap.put("message", resultJson.getString("errmsg"));
+            }
+        } catch (Exception e) {
+            returnMap.put("code", -1);
+            returnMap.put("message", "系统错误");
+        }
+        return returnMap;
+    }
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(6);
+
+    @Override
+    public void getCheckinData(String starttime, String endtime) {
+        try {
+            Map<String, Object> qywxAccessToken = getOAAccessToken();
+            if ((Integer) qywxAccessToken.get("code") != 0) {
+                log.error("员工考勤获取token失败,返回信息:{}", qywxAccessToken.get("message"));
+                throw new Exception("员工考勤获取token失败");
+            }
+            List<WechatUserList> list = wechatMapper.queryWechatUserList(0);
+            if (Check.isNull(list)) {
+                return;
+            }
+            Object accessToken = qywxAccessToken.get("accessToken");
+            list.forEach(userList -> executorService.submit(() -> addWechatCheckinData(userList, starttime, endtime, accessToken)));
+        } catch (Exception e) {
+            log.error("员工考勤入库异常,", e);
+        }
+    }
+
+    private void addWechatCheckinData(WechatUserList userList, String starttime, String endtime, Object accessToken) {
+        JSONObject params = new JSONObject();
+        String userId = userList.getUserId();
+        String departId = userList.getDepartId();
+        params.put("opencheckindatatype", 3);
+        JSONArray userArr = new JSONArray();
+        userArr.add(userId);
+        params.put("useridlist", userArr);
+        params.put("starttime", DateUtils.timeToStamp(starttime));
+        params.put("endtime", DateUtils.timeToStamp(endtime));
+        String resultStr = HttpUtils.httpPostRequestTest(QYWxConstant.QYWX_CHECKIN_DATA + "?access_token=" + accessToken, params.toJSONString(), null);
+        JSONObject resultJson = JSONObject.parseObject(resultStr);
+        if (resultJson.getInteger("errcode") == 0) {
+            JSONArray checkindata = resultJson.getJSONArray("checkindata");
+            if (!Check.isNull(checkindata)) {
+                StringBuffer buf = null;
+                String checkinType = "";
+                String checkinTypeCode = "";
+                for (int i = 0; i < checkindata.size(); i++) {
+                    JSONObject jsonObject = checkindata.getJSONObject(i);
+                    if (!Check.isNull(jsonObject)) {
+                        WechatCheckinData checkinData = new WechatCheckinData();
+                        checkinType = jsonObject.getString("checkin_type");
+                        //1上班,2下班
+                        checkinTypeCode = "上班打卡".equals(checkinType) ? "1" : "2";
+                        //下班打卡时间
+                        Long checkinTimeStamp = jsonObject.getLong("checkin_time");
+                        Date checkDate = DateUtils.stampToTime(checkinTimeStamp);
+                        String dateStr = DateUtils.formatDate(checkDate);
+                        long dateLong = DateUtils.timeToStamp(dateStr + " 00:00:00");
+                        //判断上班是否是周一,周一打卡时间超过9.35则算迟到
+                        String exceptionType = jsonObject.getString("exception_type");
+                        if ("1".equals(checkinTypeCode)) {
+                            if ("星期一".equals(DateUtils.getWhatDay(checkinTimeStamp))) {
+                                long toTime = DateUtils.timeToStamp(dateStr + " 09:36:00");
+                                if (checkinTimeStamp > toTime) {
+                                    exceptionType = Check.isNull(exceptionType) ? "时间异常" : exceptionType;
+                                }
+                            }
+                        }
+                        buf = new StringBuffer();
+                        String id = buf.append(userId).append("_").append(checkinTypeCode).append("_").append(dateLong).toString();
+                        checkinData.setId(id);
+                        checkinData.setDepartId(departId);
+                        checkinData.setUserId(userId);
+                        checkinData.setCheckinType(checkinType);
+                        checkinData.setCheckinTime(checkDate);
+                        Long dateStamp = DateUtils.timeToStamp(dateStr + " 21:30:00"); // 每天九点半时间戳
+                        if (checkinTimeStamp >= dateStamp) {
+                            checkinData.setOvertimeOrNot(1);
+                            String overtimeStr = DateUtils.formatDate(checkDate) + " 19:00:00";
+                            Long overtimeStamp = DateUtils.timeToStamp(overtimeStr); // 每天九点半时间戳
+                            Double overtime = Double.valueOf(checkinTimeStamp - overtimeStamp) / 3600;
+                            checkinData.setOvertime(overtime);
+                        } else {
+                            checkinData.setOvertimeOrNot(0);
+                        }
+                        checkinData.setWifiname(jsonObject.getString("wifiname"));
+                        checkinData.setNotes(jsonObject.getString("notes"));
+                        checkinData.setLat(jsonObject.getString("lng"));
+                        checkinData.setLocationDetail(jsonObject.getString("location_detail"));
+                        checkinData.setGroupName(jsonObject.getString("groupname"));
+                        checkinData.setDeviceid(jsonObject.getString("deviceid"));
+                        checkinData.setExceptionType(exceptionType);
+                        checkinData.setLocationTitle(jsonObject.getString("location_title"));
+                        checkinData.setWifimac(jsonObject.getString("wifimac"));
+                        checkinData.setMediaids(jsonObject.getJSONArray("mediaids").toJSONString());
+                        checkinData.setLat(jsonObject.getString("lat"));
+                        wechatMapper.insertWechatCheckinData(checkinData);
+                    }
+                }
+            }
+        } else {
+            log.error("获取打卡数据异常,返回数据-> {} ;入参-> {}", resultJson, params.toJSONString());
+        }
+    }
+
+    public Map<String, Object> getOAAccessToken() {
+        Map<String, Object> returnMap = new HashMap<>();
+        try {
+            TreeMap<String, Object> params = new TreeMap<>();
+            params.put("corpid", QYWxConstant.QYWX_CORP_ID);
+            params.put("corpsecret", QYWxConstant.QYWX_OA_CORP_SECRET);
+            String resultStr = HttpUtils.httpGet(QYWxConstant.QYWX_API_URL + QYWxConstant.QYWX_GET_TOKEN, params, null);
+            JSONObject resultJson = JSONObject.parseObject(resultStr);
+            Integer errcode = resultJson.getInteger("errcode");
+            if (errcode == 0) {
+                returnMap.put("code", 0);
+                returnMap.put("accessToken", resultJson.getString("access_token"));
+            } else {
+                returnMap.put("code", errcode);
+                returnMap.put("message", resultJson.getString("errmsg"));
+            }
+        } catch (Exception e) {
+            returnMap.put("code", -1);
+            returnMap.put("message", "系统错误");
+        }
+        return returnMap;
+    }
+
+    @Override
+    public List<WechatAttendance> queryAttendanceData(Map<String, Object> paramsMap) {
+        finishingTime(paramsMap);
+        List<WechatAttendance> list = wechatMapper.queryAttendanceData(paramsMap);
+        if (!Check.isNull(list)) {
+            checkOverTimeData(list);
+        }
+        return list;
+    }
+
+    /**
+     * 整理时间
+     */
+    private void finishingTime(Map<String, Object> paramsMap) {
+        String startTime = (String) paramsMap.get("startTime");
+        if (!Check.isNull(startTime)) {
+            startTime += " 00:00:00";
+            paramsMap.put("startTime", startTime);
+        }
+        String stopTime = (String) paramsMap.get("stopTime");
+        if (!Check.isNull(stopTime)) {
+            stopTime += " 23:59:59";
+            paramsMap.put("stopTime", stopTime);
+        }
+    }
+
+    /**
+     * 筛选10:30以后打卡的迟到数据,判断前一天是否加班,更新迟到时长
+     */
+    private void checkOverTimeData(List<WechatAttendance> list) {
+        for (WechatAttendance attendance : list) {
+            if ("迟到".equals(attendance.getType())) {
+                Integer dur = Integer.valueOf(attendance.getStateDuration().replace(" min", ""));
+                if (dur - 60 >= 0) {
+                    String checkinDate = attendance.getCheckinDate();
+                    String lastDay = DateUtils.getLastDay(checkinDate, 1);
+                    Map<String, Object> map = new HashMap<>();
+                    map.put("userId", attendance.getUserId());
+                    map.put("checkinDate", lastDay);
+                    map.put("checkinType", "下班打卡");
+                    WechatCheckinData data = wechatMapper.queryEntityByMap(map);
+                    if (!Check.isNull(data) && "1".equals(data.getOvertimeOrNot() + "")) {
+                        attendance.setStateDuration((dur - 60) + " min");
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public List<WechatAttendance> queryOverTimeData(Map<String, Object> paramsMap) {
+        finishingTime(paramsMap);
+        return wechatMapper.queryOverTimeData(paramsMap);
+    }
+}

+ 94 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/service/impl/WexinServiceImpl.java

@@ -0,0 +1,94 @@
+package cn.com.ctop.job.bytedance.service.impl;
+
+import cn.com.ctop.job.bytedance.entity.WexinConfig;
+import cn.com.ctop.job.bytedance.service.ISendMessageService;
+import cn.com.ctop.job.bytedance.utils.Check;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import lombok.val;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
+import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class WexinServiceImpl {
+
+    @Autowired
+    private ISendMessageService messageService;
+
+    private static Map<String, WexinConfig> configMap = new HashMap<>();
+
+
+    private Map<String, WexinConfig> getConfigMap() {
+        QueryWrapper<WexinConfig> queryWrapper = new QueryWrapper<>();
+        queryWrapper.orderByDesc("create_time");
+        List<WexinConfig> list = messageService.orderByDescList();
+        for (WexinConfig config : list) {
+            WxCpService wxCpService = new WxCpServiceImpl();
+            val configStorage = new WxCpDefaultConfigImpl();
+            configStorage.setCorpId(config.getCorpId());
+            configStorage.setAgentId(config.getAgentId());
+            configStorage.setCorpSecret(config.getCorpSecret());
+            configStorage.setToken(config.getToken());
+            configStorage.setAesKey(config.getAesKey());
+            wxCpService.setWxCpConfigStorage(configStorage);
+            config.setWxCpService(wxCpService);
+            configMap.put(config.getCorpId(), config);
+        }
+        return configMap;
+    }
+
+    public void sendMessage(List<JSONObject> wxUserList, String content) {
+        if (Check.isNullMap(configMap)) {
+            getConfigMap();
+        }
+        if (wxUserList != null && wxUserList.size() > 0) {
+            for (JSONObject userInfo : wxUserList) {
+                WxCpMessage message = new WxCpMessage();
+                message.setMsgType("text");
+                message.setContent(content);
+                message.setAgentId(1000002);
+                message.setToUser(userInfo.getString("wexin_id"));
+                try {
+                    WexinConfig config = configMap.get(userInfo.getString("corp_id"));
+                    WxCpService wxCpService = config.getWxCpService();
+                    wxCpService.messageSend(message);
+                } catch (WxErrorException e) {
+                    log.error("发送信息失败,userId:{}", userInfo.getString("wexin_id"));
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public void sendMessageByWeChatId(JSONObject weChatInfo, String content) {
+        if (Check.isNullMap(configMap)) {
+            this.getConfigMap();
+        }
+        if (!Check.isNull(weChatInfo)) {
+            WxCpMessage message = new WxCpMessage();
+            message.setMsgType("text");
+            message.setContent(content);
+            message.setAgentId(1000002);
+            message.setToUser(weChatInfo.getString("wexin_id"));
+            try {
+                WexinConfig config = configMap.get(weChatInfo.getString("corp_id"));
+                WxCpService wxCpService = config.getWxCpService();
+                wxCpService.messageSend(message);
+            } catch (WxErrorException e) {
+                log.error("发送信息失败,userId:{}", weChatInfo.getString("wexin_id"));
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 1 - 1
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/APIUtil.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou.utils;
+package cn.com.ctop.job.bytedance.utils;
 
 import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;

+ 1 - 1
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/Check.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou.utils;
+package cn.com.ctop.job.bytedance.utils;
 
 import com.alibaba.fastjson.JSONArray;
 import lombok.extern.slf4j.Slf4j;

File diff suppressed because it is too large
+ 1774 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/DateUtils.java


+ 278 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/ExportExcelUtils.java

@@ -0,0 +1,278 @@
+package cn.com.ctop.job.bytedance.utils;
+
+
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFFont;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public class ExportExcelUtils {
+
+
+    /**
+     * @param workbook
+     * @param sheetNum   (sheet的位置,0表示第一个表格中的第一个sheet)
+     * @param sheetTitle (sheet的名称)
+     * @param headers    (表格的标题)
+     * @param result     (表格的数据)
+     * @return
+     * @throws Exception
+     * @Title: exportExcel
+     * @Description: 导出Excel的方法
+     */
+
+    public void exportExcel(XSSFWorkbook workbook, int sheetNum,
+                            String sheetTitle, String[] headers, List<List<Object>> result) {
+        // 生成一个表格
+        XSSFSheet sheet = workbook.createSheet();
+        workbook.setSheetName(sheetNum, sheetTitle);
+        // 设置表格默认列宽度为20个字节
+        sheet.setDefaultColumnWidth((short) 20);
+        // 生成一个样式
+        XSSFCellStyle style = workbook.createCellStyle();
+        // 设置这些样式
+        style.setFillForegroundColor(IndexedColors.PALE_BLUE.index);
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBorderLeft(BorderStyle.THIN);
+        style.setBorderRight(BorderStyle.THIN);
+        style.setBorderTop(BorderStyle.THIN);
+        // style.setAlignment(HorizontalAlignment.CENTER);
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
+        // 生成一个字体
+        XSSFFont font = workbook.createFont();
+        font.setColor(IndexedColors.BLACK.index);
+        font.setFontHeightInPoints((short) 12);
+        font.setBold(true);
+        // 把字体应用到当前的样式
+        style.setFont(font);
+
+        // 指定当单元格内容显示不下时自动换行
+        style.setWrapText(true);
+
+        // 产生表格标题行
+        XSSFRow row = sheet.createRow(0);
+        for (int i = 0; i < headers.length; i++) {
+            XSSFCell cell = row.createCell((short) i);
+            cell.setCellStyle(style);
+            XSSFRichTextString text = new XSSFRichTextString(headers[i]);
+            cell.setCellValue(text.toString());
+        }
+        // 遍历集合数据,产生数据行
+        if (result != null) {
+            int index = 1;
+            for (List<Object> m : result) {
+                row = sheet.createRow(index);
+                int cellIndex = 0;
+                for (Object obj : m) {
+                    XSSFCell cell = row.createCell((short) cellIndex);
+                    if (!Check.isNull(obj)) {
+                        if (obj instanceof String) {
+                            cell.setCellValue((String) obj);
+                        } else if (obj instanceof Double) {
+                            cell.setCellValue((Double) obj);
+                        } else if (obj instanceof BigDecimal) {
+                            BigDecimal bigDecimal = (BigDecimal) obj;
+                            cell.setCellValue(bigDecimal.doubleValue());
+                        } else if (obj instanceof Long) {
+                            cell.setCellValue(String.valueOf(obj));
+                        } else {
+                            cell.setCellValue(obj.toString());
+                        }
+                    } else {
+                        cell.setCellValue(0);
+                    }
+
+                    cellIndex++;
+                }
+                index++;
+            }
+        }
+    }
+
+
+    public void exportExcelForAttendance(XSSFWorkbook workbook, int sheetNum, String sheetTitle, String[] headers, List<List<Object>> result) {
+        // 生成一个表格
+        XSSFSheet sheet = workbook.createSheet();
+        workbook.setSheetName(sheetNum, sheetTitle);
+        // 设置表格默认列宽度为20个字节
+        sheet.setDefaultColumnWidth((short) 20);
+        // 生成一个样式
+        XSSFCellStyle style = workbook.createCellStyle();
+        XSSFCellStyle style2 = workbook.createCellStyle();
+        XSSFCellStyle style3 = workbook.createCellStyle();
+        // 设置这些样式
+        style.setFillForegroundColor(IndexedColors.PALE_BLUE.index);
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBorderLeft(BorderStyle.THIN);
+        style.setBorderRight(BorderStyle.THIN);
+        style.setBorderTop(BorderStyle.THIN);
+        // style.setAlignment(HorizontalAlignment.CENTER);
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
+        // 生成一个字体
+        XSSFFont font = workbook.createFont();
+        font.setColor(IndexedColors.BLACK.index);
+        font.setFontHeightInPoints((short) 12);
+        font.setBold(true);
+        // 把字体应用到当前的样式
+        style.setFont(font);
+
+        // 指定当单元格内容显示不下时自动换行
+        style.setWrapText(true);
+        //迟到时间超过15分钟的考勤记录样式(标黄)
+        style2.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.index);
+        style2.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        style2.setBorderBottom(BorderStyle.THIN);
+        style2.setBorderLeft(BorderStyle.THIN);
+        style2.setBorderRight(BorderStyle.THIN);
+        style2.setBorderTop(BorderStyle.THIN);
+        // 产生表格标题行
+        XSSFRow row = sheet.createRow(0);
+        for (int i = 0; i < headers.length; i++) {
+            XSSFCell cell = row.createCell((short) i);
+            cell.setCellStyle(style);
+            XSSFRichTextString text = new XSSFRichTextString(headers[i]);
+            cell.setCellValue(text.toString());
+        }
+        // 遍历集合数据,产生数据行
+        if (result != null) {
+            int index = 1;
+            for (List<Object> m : result) {
+                row = sheet.createRow(index);
+                int cellIndex = 0;
+                //迟到时间超过15分钟的考勤记录判断
+                boolean changeColor = false;
+                if (m.contains("迟到")) {
+                    String duration = String.valueOf(m.get(m.size() - 2));
+                    if (!Check.isNull(duration) && Integer.valueOf(duration.replace(" min", "")) - 10 > 0) {
+                        changeColor = true;
+                    }
+                }
+                for (Object obj : m) {
+                    XSSFCell cell = row.createCell((short) cellIndex);
+                    if (!Check.isNull(obj)) {
+                        if (changeColor) {
+                            cell.setCellStyle(style2);
+                        }
+                        if (obj instanceof String) {
+                            cell.setCellValue((String) obj);
+                        } else if (obj instanceof Double) {
+                            cell.setCellValue((Double) obj);
+                        } else if (obj instanceof BigDecimal) {
+                            BigDecimal bigDecimal = (BigDecimal) obj;
+                            cell.setCellValue(bigDecimal.doubleValue());
+                        } else if (obj instanceof Long) {
+                            cell.setCellValue(String.valueOf(obj));
+                        } else {
+                            cell.setCellValue(obj.toString());
+                        }
+                    }
+                    cellIndex++;
+                }
+                index++;
+            }
+        }
+    }
+
+    public void exportExcelForMediaReport(XSSFWorkbook workbook, int sheetNum, String sheetTitle, String[] headers, List<List<Object>> result) {
+        // 生成一个表格
+        XSSFSheet sheet = workbook.createSheet();
+        workbook.setSheetName(sheetNum, sheetTitle);
+        // 设置表格默认列宽度为20个字节
+        sheet.setDefaultColumnWidth((short) 20);
+        sheet.setColumnWidth(0, 15 * 256);
+        sheet.setColumnWidth(1, 40 * 256);
+        sheet.setColumnWidth(2, 30 * 256);
+        sheet.setColumnWidth(3, 35 * 256);
+        sheet.setColumnWidth(4, 20 * 256);
+        sheet.setColumnWidth(5, 20 * 256);
+        sheet.setColumnWidth(6, 20 * 256);
+        sheet.setColumnWidth(7, 20 * 256);
+        sheet.setColumnWidth(8, 15 * 256);
+        // 生成一个样式
+        XSSFCellStyle style = workbook.createCellStyle();
+        // 设置这些样式
+        style.setFillForegroundColor(IndexedColors.PALE_BLUE.index);
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        style.setBorderBottom(BorderStyle.THIN);
+        style.setBorderLeft(BorderStyle.THIN);
+        style.setBorderRight(BorderStyle.THIN);
+        style.setBorderTop(BorderStyle.THIN);
+        // style.setAlignment(HorizontalAlignment.CENTER);
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
+        // 生成一个字体
+        XSSFFont font = workbook.createFont();
+        font.setColor(IndexedColors.BLACK.index);
+        font.setFontHeightInPoints((short) 12);
+        font.setBold(true);
+        // 把字体应用到当前的样式
+        style.setFont(font);
+
+        // 指定当单元格内容显示不下时自动换行
+        style.setWrapText(true);
+
+        //同一行第一个cell
+        XSSFCellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+        cellStyle.setWrapText(true);
+
+        // 产生表格标题行
+        XSSFRow row = sheet.createRow(0);
+        for (int i = 0; i < headers.length; i++) {
+            XSSFCell cell = row.createCell((short) i);
+            cell.setCellStyle(style);
+            XSSFRichTextString text = new XSSFRichTextString(headers[i]);
+            cell.setCellValue(text.toString());
+        }
+        // 遍历集合数据,产生数据行
+        if (result != null) {
+            int index = 1;
+            for (List<Object> m : result) {
+                row = sheet.createRow(index);
+                int cellIndex = 0;
+
+                for (Object obj : m) {
+                    XSSFCell cell = row.createCell((short) cellIndex);
+                    if (!Check.isNull(obj)) {
+                        if (obj instanceof String) {
+                            cell.setCellValue((String) obj);
+                        } else if (obj instanceof Double) {
+                            cell.setCellValue((Double) obj);
+                        } else if (obj instanceof BigDecimal) {
+                            BigDecimal bigDecimal = (BigDecimal) obj;
+                            cell.setCellValue(bigDecimal.doubleValue());
+                        } else if (obj instanceof Long) {
+                            cell.setCellValue(String.valueOf(obj));
+                        } else {
+                            cell.setCellValue(obj.toString());
+                        }
+                    } else {
+                        cell.setCellValue(0);
+                    }
+                    cell.setCellStyle(cellStyle);
+
+                    cellIndex++;
+                }
+                index++;
+            }
+        }
+    }
+
+
+}

+ 1 - 1
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/HttpGetWithBodyEntity.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou.utils;
+package cn.com.ctop.job.bytedance.utils;
 
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 

+ 1 - 1
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/HttpUtil.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou.utils;
+package cn.com.ctop.job.bytedance.utils;
 
 import com.alibaba.fastjson.JSONObject;
 import com.google.gson.Gson;

File diff suppressed because it is too large
+ 1024 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/HttpUtils.java


+ 1 - 1
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/KuaishouAPIConstant.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou.utils;
+package cn.com.ctop.job.bytedance.utils;
 
 /**
  * 快手磁力金牛API接口常量

+ 38 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/QYWxConstant.java

@@ -0,0 +1,38 @@
+package cn.com.ctop.job.bytedance.utils;
+
+public class QYWxConstant {
+    //企业ID
+    public static final String QYWX_CORP_ID = "ww24b8a47826f5875f";
+    //okr
+    public static final String QYWX_CORP_SECRET = "1YWGDtuZWrQDl6US3OPHG8_pvuNgP1TeUsOmfRk6GmQ";
+
+    //打卡
+    public static final String QYWX_OA_CORP_SECRET = "MDeiFSCwIlcmcR1zrYvmjNlsoYFGl8I770uuUezWgGE";
+    //审批
+    public static final String QYWX_APPROVA_CORP_SECRET = "qlk4nSc1vjxy0AHyX1f5bnGh7y2WtqN9lR__0WJA6zM";
+
+
+    public static final String QYWX_API_URL = "https://qyapi.weixin.qq.com";  //企业微信api域名
+    public static final String QYWX_DEPART_LIST = "https://qyapi.weixin.qq.com/cgi-bin/department/list";  //获取部门列表
+    public static final String QYWX_GET_TOKEN = "/cgi-bin/gettoken";  //获取token
+    public static final String QYWX_USER_SIMPLELIST = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist";  //获取部门下员工简单信息
+    public static final String QYWX_CHECKIN_DATA = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata";  //获取部门下员工简单信息
+    public static final String APP_ROVAL_INFO = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovalinfo";  //批量获取审批单号
+    public static final String APP_ROVAL_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail";  //获取审批申请详情
+    public static final String APPCHAT_CREATE = "https://qyapi.weixin.qq.com/cgi-bin/appchat/create";  //创建群聊
+    public static final String APPCHAT_GET = "https://qyapi.weixin.qq.com/cgi-bin/appchat/get";  //创建群聊
+    public static final String APPCHAT_SEND = "https://qyapi.weixin.qq.com/cgi-bin/appchat/send"; // 发送消息
+
+    /**
+     * 天津优容智汇 企业微信信息
+     */
+    //企业ID
+    public static final String YR_CORP_ID = "wwec72c7e61a7840b2";
+    //考勤统计
+    public static final String YR_CORP_SECRET = "AeykrKAY-OoEM7P46Xr6rJB9aa28BLK9VO2hrS0g3S8";
+    //打卡
+    public static final String YR_OA_CORP_SECRET = "AUhGy8TOTenCbdsxyW-QtrYN7mA5Pj7ou_YF52-M-GE";
+    //审批
+    public static final String YR_APPROVA_CORP_SECRET = "XRw6j6gVCV4oXfFDtheIanp0pf8QLuVgDLQiFx3Fa1E";
+
+}

+ 1 - 1
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/Result.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.job.kuaishou.utils;
+package cn.com.ctop.job.bytedance.utils;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import io.swagger.annotations.ApiModel;

+ 31 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/ResultMapUtils.java

@@ -0,0 +1,31 @@
+package cn.com.ctop.job.bytedance.utils;
+
+import java.util.Map;
+
+/**
+ * @author jeecg-boot
+ * 2019年12月5日19:57:58
+ */
+public class ResultMapUtils {
+    private static final String MAP_CODE = "code";
+    private static final String MAP_MESSAGE = "message";
+    private static final String MAP_SUCCESS = "success";
+
+    public static void setResultMap(Map<String, Object> map, Integer statusCode) {
+        map.put(MAP_CODE, statusCode);
+        map.put(MAP_MESSAGE, StatusCode.getDesc(statusCode));
+        map.put(MAP_SUCCESS, StatusCode.getFlag(statusCode));
+    }
+
+    public static void setResultMap(Map<String, Object> map, StatusCode statusCode) {
+        map.put(MAP_CODE, statusCode.getCode());
+        map.put(MAP_MESSAGE, statusCode.getDesc());
+        map.put(MAP_SUCCESS, statusCode.getFlag());
+    }
+
+    public static void setResultMap(Map<String, Object> map, int statusCode,String message,boolean flag) {
+        map.put(MAP_CODE, statusCode);
+        map.put(MAP_MESSAGE, message);
+        map.put(MAP_SUCCESS, flag);
+    }
+}

+ 61 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/SpNoEnum.java

@@ -0,0 +1,61 @@
+package cn.com.ctop.job.bytedance.utils;
+
+
+public enum SpNoEnum {
+
+
+    control1("Attendance", "假勤"),
+    control2("Vacation", "请假"),
+    control3("PunchCorrection", "补卡"),
+    type1("1", "请假"),
+    type2("2", "补卡"),
+    type3("3", "出差"),
+    type4("4", "外出"),
+    type5("5", "加班"),
+    vacation1("101","年假"),
+    vacation2("102","事假"),
+    vacation3("103","病假"),
+    vacation4("104","调休"),
+    vacation5("105","婚假"),
+    vacation6("106","产假"),
+    vacation7("107","陪产假"),
+    vacation8("108","其他"),
+    vacation9("109","丧假");
+    private String code;
+    private String name;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public static SpNoEnum getSpNoEnum(String code) {
+        if (Check.isNull(code)) {
+            return null;
+        }
+        for (SpNoEnum value : SpNoEnum.values()) {
+            if (value.code.equals(code)) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+
+    private SpNoEnum(String code, String name) {
+        this.code = code;
+        this.name = name;
+
+    }
+}

+ 124 - 0
job-bytedance/src/main/java/cn/com/ctop/job/bytedance/utils/StatusCode.java

@@ -0,0 +1,124 @@
+package cn.com.ctop.job.bytedance.utils;
+
+/**
+ * @author jeecg-boot
+ * 2019年12月5日19:57:58
+ */
+public enum StatusCode {
+    /**
+     * 0   请求成功
+     * -101 参数异常
+     * -102 服务器异常
+     * -103 数据不存在
+     * -104 渠道不存在
+     * -105 规则尚未配置
+     * -106 规则为空
+     * -107 同盾数据为空
+     * -108 模型服务异常
+     * -109 深度搜索服务异常
+     * -201 探针数据为空
+     */
+    COMMON_SUCCESS("操作成功", 0, true),
+    COMMON_PARAM_ERROR("参数异常", -1, false),
+    COMMON_ACCOUNT_ERROR("参数异常", -2, false),
+    COMMON_INTERNET_ERROR("网络请求异常", -3, false),
+    COMMON_DATA_NOT_EXIST("数据不存在或者已经被删除", -101, false),
+    BYTEDANCE_PLAN_DATA_NOT_EXIST("此计划不存在或者已经被删除", -101, false),
+    BYTEDANCE_ACCOUNT_DATA_NOT_EXIST("此账户尚未绑定或已停投", -101, false),
+    COMMON_VERSION_NOT_EXIST("版本号不存在", -102, false),
+    BYTEDANCE_VIDEO_UPLOAD_FAIL("今日头条视频文件上传失败", -201, false),
+    MATERIAL_UPLOAD_FAIL("素材文件上传失败", -201, false),
+    IMAGE_NUMBER_SHORTAGE("今日头条图片文件上传失败", -202, false),
+    BYTEDANCE_IMAGE_UPLOAD_FAIL("今日头条图片文件上传失败", -203, false),
+    TEMPLATE_NAME_HAS_EXIST("模板名称已存在", -204, false),
+    TEMPLATE_NAME_IS_NULL("模板名称为空", -205, false),
+    FILE_HAS_NOT_UPLOAD("文件尚未上传", -206, false),
+    ACCOUNT_HAS_NOT_EXIST("该用户信息不存在", -207, false),
+    USERNAME_OR_PASSWORD_ERROR("登录用户名或密码错误", -208, false),
+    ACCOUNT_HAS_NO_AUTHORIZE("该用户尚未进行授权", -209, false),
+    FILE_HAS_UPLOAD("文件已经上传过", 0, false),
+    COMMON_SERVER_ERROR("服务器内部错误", -102, false),
+    CTOP_HAS_NO_PERFORMANCE_STATISTIC_LOGIC("绩效统计逻辑尚未确定", -103, false),
+    CTOP_SCRIPT_FILE_NOT_EXIST("脚本文件不存在", -104, false),
+    CTOP_PROJECT_NOT_EXIST("项目不存在", -105, false),
+    CTOP_FEISHU_EMAIL_NOT_EXIST("飞书账户未绑定邮箱", -106, false),
+    CTOP_FEISHU_ACCOUNT_NOT_EXIST("该用户未注册系统账户,请联系管理员", -107, false),
+
+    KUAISHOU_CRAWLER_APP_EXIT("快手app异常退出", -1001, false),
+    KUAISHOU_CRAWLER_APP_ELEMENT_ERROR("快手元素异常", -1002, false),
+    KUAISHOU_CRAWLER_APP_ELEMENT_IS_NULL("此快手元素获取不到", -1003, false),
+    KUAISHOU_CRAWLER_APP_MOBILE_CODE_IS_NULL("短信验证码未获取到", -1004, false),
+    KUAISHOU_CRAWLER_APP_ELEMENT_DETAIL_ERROR("快手元素内容异常", -1005, false),
+    KUAISHOU_CRAWLER_APP_NO_ENABLED_DEVICE("暂无可用设备", -2001, false),
+    KUAISHOU_OPTINIZER_CONFIG_IS_NULL("快手媒体优化师配置信息不全", -3001, false),
+    KUAISHOU_OPTINIZER_PERSONNAL_DATA_IS_NULL("快手媒体优化师个人消耗数据不存在", -3002, false),
+    BYTEDANCE_OPTINIZER_PERSONNAL_DATA_IS_NULL("头条媒体优化师个人消耗数据不存在", -3003, false),
+    OPTINIZER_PERSONNAL_DATA_IS_NULL("优化师个人消耗数据不存在", -3004, false),
+
+    BYTEDACNE_API_GROUP_CREATE_ERROR("头条API创建广告组异常",-4001,false),
+
+    KUAISHOU_API_ACCOUNT_SPEED_EXPLORING("此账户加速探索尚未完成",-5001,false),
+    KUAISHOU_SPEED_EXPLORE_ACTION_TYPE_NOT_CONFIG("加速探索尚不支持此类优化目标",-5002,false),
+    KUAISHOU_SPEED_EXPLORE_FAIL("加速探索失败",-5003,false),
+
+    KUAISHOU_AI_STRATEGY_HAS_NOT_EXIST("账户策略未配置或者已经被关闭",-6001,false),
+    KUAISHOU_AI_STRATEGY_HAS_NO_HISTORY_MATERIAL("历史素材不存在",-6002,false),
+
+    KUAISHOU_CRAWLER_APP_SUCCESS("爬虫运行正常", 0, true),
+    KUAISHOU_CRAWLER_APP_TASK_END("爬虫任务运行结束", 1, true),
+    KUAISHOU_CRAWLER_APP_JOB_StART("任务开始执行开始", 0, true),
+    KUAISHOU_CRAWLER_APP_JOB_END("任务运行结束", 1, true),
+    MODEL_VIDEO_NOT_EXIST("模板视频不存在或者已经被删除", 0, false);
+    private String desc;
+    private int code;
+    private boolean flag;
+
+    StatusCode(String desc, int code, boolean flag) {
+        this.desc = desc;
+        this.code = code;
+        this.flag = flag;
+    }
+
+    public static String getDesc(int code) {
+        for (StatusCode error : StatusCode.values()) {
+            if (error.getCode() == code) {
+                return error.getDesc();
+            }
+        }
+        return null;
+    }
+
+    public static Boolean getFlag(int code) {
+        for (StatusCode error : StatusCode.values()) {
+            if (error.getCode() == code) {
+                return error.getFlag();
+            }
+        }
+        return null;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public boolean getFlag() {
+        return flag;
+    }
+
+    public void setFlag(boolean flag) {
+        this.flag = flag;
+    }
+
+}

+ 12 - 15
kuaishou/src/main/resources/application.yml

@@ -1,5 +1,5 @@
 server:
-  port: 8086
+  port: 8087
   ip: 127.0.0.1
   servlet:
     context-path: /
@@ -75,10 +75,14 @@ spring:
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master:
-          url: jdbc:mysql://139.186.27.96:3390/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
-          username: data
-          password: hcst@2021
-          driver-class-name: com.mysql.jdbc.Driver
+        #          url: jdbc:mysql://139.186.27.96:3390/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8
+        #          username: data
+        #          password: hcst@2021
+        #---------------------测试库
+         url: jdbc:mysql://139.186.165.84:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&allowMultiQueries=true
+         username: hcst
+         password: hcst@2020
+         driver-class-name: com.mysql.jdbc.Driver
 
 #mybatis plus 设置
 mybatis-plus:
@@ -104,18 +108,11 @@ xxl:
   job:
     accessToken:
     executor:
-      appname: module-job-kuaishou
-      port: 9997
+      appname: module-job-bytedance
+      port: 9998
       ip:
       logpath: /data/applogs/xxl-job/jobhandler
       logretentiondays: 30
     admin:
-      addresses: http://192.168.0.192:8080/xxl-job-admin
-api:
-  kuaishou:
-    postUrl: https://ad.e.kuaishou.com
-
-report:
-  #启动宇鹏整理数据的服务IP
-  start_ip_path: http://192.168.0.203:3456/
+      addresses: http://139.186.29.76:8090/xxl-job-admin
 

kuaishou/src/main/resources/log4j.properties → job-bytedance/src/main/resources/log4j.properties


kuaishou/src/main/resources/logback-dev.xml → job-bytedance/src/main/resources/logback-dev.xml


kuaishou/src/main/resources/logback-prod.xml → job-bytedance/src/main/resources/logback-prod.xml


kuaishou/src/main/resources/logback-test.xml → job-bytedance/src/main/resources/logback-test.xml


kuaishou/src/test/java/cn/com/ctop/job/kuaishou/SampleTest.java → job-bytedance/src/test/java/cn/com/ctop/job/bytedance/SampleTest.java


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

@@ -1,27 +0,0 @@
-package cn.com.ctop.job.controller;
-
-import io.swagger.annotations.Api;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-
-@RestController
-@RequestMapping("/kuaishouController")
-@Api(tags = "快手直播")
-@Slf4j
-public class KuaishouController {
-
-   /* @Autowired
-    private AgentTokenService tokenService;*/
-
-
-    @GetMapping(value = "/test")
-    public String test(Long accountId) {
-        System.out.println("ok");
-        return "ok";
-    }
-
-
-}

+ 0 - 382
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/DateUtils.java

@@ -1,382 +0,0 @@
-package cn.com.ctop.job.kuaishou.utils;
-
-import org.apache.commons.lang3.time.DateFormatUtils;
-
-import java.lang.management.ManagementFactory;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 时间工具类
- *
- * @author ruoyi
- */
-public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
-    public static String YYYY = "yyyy";
-
-    public static String YYYY_MM = "yyyy-MM";
-
-    public static String YYYY_MM_DD = "yyyy-MM-dd";
-
-    public static String YYYYMMDD = "yyyyMMdd";
-
-    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
-
-    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
-
-    private static String[] parsePatterns = {
-            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
-            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
-            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
-
-    /**
-     * 获取当前Date型日期
-     *
-     * @return Date() 当前日期
-     */
-    public static Date getNowDate() {
-        return new Date();
-    }
-
-    /**
-     * 获取当前日期, 默认格式为yyyy-MM-dd
-     *
-     * @return String
-     */
-    public static String getDate() {
-        return dateTimeNow(YYYY_MM_DD);
-    }
-
-    public static final String getTime() {
-        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
-    }
-
-    public static final String dateTimeNow() {
-        return dateTimeNow(YYYYMMDDHHMMSS);
-    }
-
-    public static final String dateTimeNow(final String format) {
-        return parseDateToStr(format, new Date());
-    }
-
-    public static final String dateTime(final Date date) {
-        return parseDateToStr(YYYY_MM_DD, date);
-    }
-
-    public static final String parseDateToStr(final String format, final Date date) {
-        return new SimpleDateFormat(format).format(date);
-    }
-
-    public static final Date dateTime(final String format, final String ts) {
-        try {
-            return new SimpleDateFormat(format).parse(ts);
-        } catch (ParseException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * 日期路径 即年/月/日 如2018/08/08
-     */
-    public static final String datePath() {
-        Date now = new Date();
-        return DateFormatUtils.format(now, "yyyy/MM/dd");
-    }
-
-    /**
-     * 日期路径 即年/月/日 如20180808
-     */
-    public static final String dateTime() {
-        Date now = new Date();
-        return DateFormatUtils.format(now, "yyyyMMdd");
-    }
-
-    /**
-     * 日期型字符串转化为日期 格式
-     */
-    public static Date parseDate(Object str) {
-        if (str == null) {
-            return null;
-        }
-        try {
-            return parseDate(str.toString(), parsePatterns);
-        } catch (ParseException e) {
-            return null;
-        }
-    }
-
-    /**
-     * 获取服务器启动时间
-     */
-    public static Date getServerStartDate() {
-        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
-        return new Date(time);
-    }
-
-    /**
-     * 计算相差天数
-     */
-    public static int differentDaysByMillisecond(Date date1, Date date2) {
-        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
-    }
-
-    /**
-     * 计算两个时间差
-     */
-    public static String getDatePoor(Date endDate, Date nowDate) {
-        long nd = 1000 * 24 * 60 * 60;
-        long nh = 1000 * 60 * 60;
-        long nm = 1000 * 60;
-        // long ns = 1000;
-        // 获得两个时间的毫秒时间差异
-        long diff = endDate.getTime() - nowDate.getTime();
-        // 计算差多少天
-        long day = diff / nd;
-        // 计算差多少小时
-        long hour = diff % nd / nh;
-        // 计算差多少分钟
-        long min = diff % nd % nh / nm;
-        // 计算差多少秒//输出结果
-        // long sec = diff % nd % nh % nm / ns;
-        return day + "天" + hour + "小时" + min + "分钟";
-    }
-
-    /**
-     * 增加 LocalDateTime ==> Date
-     */
-    public static Date toDate(LocalDateTime temporalAccessor) {
-        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
-        return Date.from(zdt.toInstant());
-    }
-
-    /**
-     * 增加 LocalDate ==> Date
-     */
-    public static Date toDate(LocalDate temporalAccessor) {
-        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
-        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
-        return Date.from(zdt.toInstant());
-    }
-
-
-    /**
-     * 时间字符串转long类型
-     * 2022-05-01 ===>>>> 20220501
-     *
-     * @param date
-     * @return
-     */
-    public static Long strDateToInt(String date) {
-
-        return Long.valueOf(date.replaceAll("-", ""));
-    }
-
-
-    /**
-     * @param
-     * @description: 获取当前周的开始和截至时间
-     * @return: java.util.Map
-     * @author: zianY
-     * @time: 2022/6/1
-     */
-    public static Map getWeekBeginAndEnd() {
-        Map<String, String> timeMap = new HashMap<>();
-        String begin = parseDateToStr(YYYY_MM_DD, getBeginDayOfWeek());
-        String end = parseDateToStr(YYYY_MM_DD, getEendDayOfWeek());
-        timeMap.put("begin", begin + " 00:00:00");
-        timeMap.put("end", end + " 23:59:59");
-        return timeMap;
-    }
-
-
-    /**
-     * @param
-     * @description: 获取本周开始时间
-     * @return: java.util.Date
-     * @author: zianY
-     * @time: 2022/6/1
-     */
-    public static Date getBeginDayOfWeek() {
-        Date date = new Date();
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(date);
-        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
-        if (dayOfWeek == 1) {
-            dayOfWeek += 7;
-        }
-        cal.add(Calendar.DATE, 2 - dayOfWeek);
-        return cal.getTime();
-    }
-
-    /**
-     * @param
-     * @description: 获取本周结束时间
-     * @return: java.util.Date
-     * @author: zianY
-     * @time: 2022/6/1
-     */
-    public static Date getEendDayOfWeek() {
-
-        Calendar cal = Calendar.getInstance();
-        cal.setTime(getBeginDayOfWeek());
-        cal.add(Calendar.DAY_OF_WEEK, 6);
-        return cal.getTime();
-    }
-
-    /**
-     * 指定模式的时间格式
-     */
-    private static SimpleDateFormat getSDFormat(String pattern) {
-        return new SimpleDateFormat(pattern);
-    }
-
-    /**
-     * 指定日期按指定格式显示
-     */
-    public static String formatDate(Date date, String pattern) {
-        return getSDFormat(pattern).format(date);
-    }
-
-
-    /**
-     * 日期转换为时间戳
-     */
-    public static long timeToStamp(String timers) {
-        Date d = new Date();
-        long timeStemp = 0;
-        try {
-            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-            // 日期转换为时间戳
-            d = sf.parse(timers);
-        } catch (ParseException e) {
-            e.printStackTrace();
-        }
-        timeStemp = d.getTime();
-        return timeStemp;
-    }
-
-    /**
-     * 返回 日期 - 天数 的string 日期
-     *
-     * @param time        时间
-     * @param daysBetween 天数
-     * @return
-     */
-    public static String getSubtractTime(Date time, Integer daysBetween) {
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        Calendar rightNow = Calendar.getInstance();
-        rightNow.setTime(time);
-        if (daysBetween.intValue() > 0) {
-            rightNow.add(Calendar.DAY_OF_YEAR, -daysBetween.intValue());
-        } else {
-            rightNow.add(Calendar.DAY_OF_YEAR, -1);
-        }
-        Date rightNowTime = rightNow.getTime();
-        String nowTime = sdf.format(rightNowTime);
-        return nowTime;
-    }
-
-    /**
-     * 时间戳转换为字符串
-     */
-    public static String timestampToStr(Long timestamp) {
-        Date date = new Date();
-        date.setTime(timestamp);
-        return (DateFormatUtils.format(date, YYYYMMDD));
-    }
-
-    /**
-     * 获取当前小时数
-     */
-    public static Integer getHourNumber() {
-        GregorianCalendar calendar = new GregorianCalendar();
-        return calendar.get(Calendar.HOUR_OF_DAY);
-    }
-
-
-    public static int dateDiff(String start, String end) {
-        //设置转换的日期格式
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        //开始时间
-        Date startDate = null;
-        Date endDate = null;
-        try {
-            startDate = sdf.parse(start);
-            endDate = sdf.parse(end);
-        } catch (ParseException e) {
-            e.printStackTrace();
-        }
-
-        //得到相差的天数 betweenDate
-        long betweenDate = (endDate.getTime() - startDate.getTime()) / (60 * 60 * 24 * 1000);
-        return (int) betweenDate;
-    }
-
-    /***
-     * 两日期之间相差天数
-     * @param dateStart
-     * @param dateEnd
-     * @return
-     */
-    public static long getDiscrepantDays(String dateStart, String dateEnd) {
-        //设置转换的日期格式
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        //结束时间
-        Date startDate = null;
-        Date endDate = null;
-        try {
-            //开始时间
-            startDate = sdf.parse(dateStart);
-            endDate = sdf.parse(dateEnd);
-        } catch (ParseException e) {
-            e.printStackTrace();
-        }
-        //得到相差的天数 betweenDate
-        return (endDate.getTime() - startDate.getTime()) / (60 * 60 * 24 * 1000);
-    }
-
-
-    /**
-     * 日期中获取月份
-     *
-     * @param format
-     * @param date
-     * @return
-     * @throws ParseException
-     */
-    public static String getMonth(String format, String date) {
-        SimpleDateFormat df = new SimpleDateFormat(format);
-        Date parse = null;
-        try {
-            parse = df.parse(date);
-        } catch (ParseException e) {
-            e.printStackTrace();
-        }
-        return String.format("%tm", parse);
-    }
-
-
-    public static void main(String[] args) {
-        List<Integer> l = new ArrayList<>();
-        int a = 1;
-        int b =(a++);
-        l.add(a);
-        l.add(b);
-        l.forEach(System.out::print);
-        System.out.println(a);
-        System.out.println(b);
-    }
-
-}

+ 0 - 137
kuaishou/src/main/java/cn/com/ctop/job/kuaishou/utils/HttpUtils.java

@@ -1,137 +0,0 @@
-package cn.com.ctop.job.kuaishou.utils;
-
-import com.alibaba.fastjson.JSONObject;
-import com.google.gson.Gson;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.CookieStore;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.CookieSpecs;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.conn.ssl.TrustStrategy;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.BasicCookieStore;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.ssl.SSLContextBuilder;
-import org.apache.http.util.EntityUtils;
-
-import javax.net.ssl.SSLContext;
-import java.nio.charset.Charset;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-@Slf4j
-public class HttpUtils {
-
-  public static CookieStore COOKIESTORE = new BasicCookieStore();
-  /** setProxy(new HttpHost("106.125.239.179", 4245)) */
-  public static Map<String, Map<String, String>> fontsMap = new HashMap<>();
-
-  public static String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36";
-
-  public static CloseableHttpClient createSslClientDefault() {
-    try {
-      SSLContext sslContext =
-          new SSLContextBuilder()
-              .loadTrustMaterial(
-                  null,
-                  new TrustStrategy() {
-                    // 信任所有证书
-                    @Override
-                    public boolean isTrusted(X509Certificate[] chain, String authType)
-                        throws CertificateException {
-                      return true;
-                    }
-                  })
-              .build();
-      RequestConfig globalConfig =
-          RequestConfig.custom()
-              .setConnectTimeout(30000)
-              .setSocketTimeout(30000)
-              .setCookieSpec(CookieSpecs.STANDARD)
-              .build();
-      SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext);
-      return HttpClients.custom()
-          .setDefaultCookieStore(COOKIESTORE)
-          .setDefaultRequestConfig(globalConfig)
-          .setConnectionReuseStrategy((response, context) -> false)
-          .setSSLSocketFactory(sslFactory)
-          .build();
-    } catch (Exception e) {
-      log.error("处理Https证书异常", e);
-    }
-    return HttpClients.createDefault();
-  }
-
-  public static String httpPostRequest(String url, Map<String, Object> param, Map<String, String> headers) {
-    HttpClient httpClient = createSslClientDefault();
-    String strReturn = "";
-    try {
-      HttpPost httppost = new HttpPost(url);
-      httppost.setHeader("User-Agent", USER_AGENT);
-      httppost.addHeader("Content-Type", "application/json");
-      if (headers != null && headers.size() > 0) {
-        for (String key : headers.keySet()) {
-          httppost.setHeader(key, headers.get(key));
-        }
-      }
-      if (param != null && param.size() > 0) {
-        httppost.setEntity(new StringEntity(new Gson().toJson(param), Charset.forName("UTF-8")));
-      }
-      RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(300 * 1000).setConnectTimeout(300 * 1000).build();
-      httppost.setConfig(requestConfig);
-      HttpEntity respentity;
-
-      HttpResponse response = httpClient.execute(httppost);
-      int statusCode = response.getStatusLine().getStatusCode();
-      if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
-        String newUrl = response.getFirstHeader("Location").getValue();
-        return httpPostRequest(newUrl, param, headers);
-      } else if (statusCode == HttpStatus.SC_OK) {
-        respentity = response.getEntity();
-        strReturn = EntityUtils.toString(respentity);
-        return strReturn;
-      }
-    } catch (Exception e) {
-      e.printStackTrace();
-      log.error(e.getMessage());
-    }
-    return strReturn;
-  }
-
-
-  public static String httpGetRequest(String url, Map<String, String> headers, JSONObject params) {
-    HttpClient httpClient = createSslClientDefault();
-    String strReturn = "";
-    try {
-      HttpGetWithBodyEntity httpGet = new HttpGetWithBodyEntity(url);
-      if (headers != null) {
-        Iterator<String> keyIter = headers.keySet().iterator();
-        while (keyIter.hasNext()) {
-          String curKey = keyIter.next();
-          if (curKey != null && headers.get(curKey) != null) {
-            httpGet.addHeader(curKey, headers.get(curKey));
-          }
-        }
-      }
-      httpGet.setEntity(new StringEntity(params.toJSONString(), Charset.forName("UTF-8")));
-      HttpEntity respentity;
-      HttpResponse response = httpClient.execute(httpGet);
-      respentity = response.getEntity();
-      strReturn = EntityUtils.toString(respentity);
-    } catch (Exception e) {
-      e.printStackTrace();
-      log.error(e.getMessage());
-    }
-    return strReturn;
-  }
-
-}

+ 2 - 2
pom.xml

@@ -2,7 +2,7 @@
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>com.xuxueli</groupId>
-	<artifactId>online-job-kuaishou</artifactId>
+	<artifactId>online-job-bytedance</artifactId>
 	<version>1.1</version>
 	<packaging>pom</packaging>
 
@@ -12,7 +12,7 @@
 
 	<modules>
 		<module>xxl-job-core</module>
-		<module>kuaishou</module>
+		<module>job-bytedance</module>
     </modules>
 
 	<properties>

+ 1 - 1
xxl-job-core/pom.xml

@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>com.xuxueli</groupId>
-		<artifactId>online-job-kuaishou</artifactId>
+		<artifactId>online-job-bytedance</artifactId>
 		<version>1.1</version>
 	</parent>
 	<artifactId>xxl-job-core</artifactId>