Parcourir la source

Merge branch 'V1.1.3' into batch

yumeng il y a 4 ans
Parent
commit
5b23f9285a
90 fichiers modifiés avec 3820 ajouts et 311 suppressions
  1. 2 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
  2. 1 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/BindAccountAuthController.java
  3. 2 2
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/BytedanceVideoEtlInfoController.java
  4. 9 10
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CallbackController.java
  5. 2 2
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouVideoEtlInfoController.java
  6. 3 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/MaterialCutFrameController.java
  7. 151 33
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TestController.java
  8. 1 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/orderplatform/mapper/xml/PlatformScriptMapper.xml
  9. 24 11
      jeecg-boot-module-system/src/main/resources/application-jiaoyang.yml
  10. 81 10
      jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java
  11. 246 0
      module-common/src/main/java/cn/com/ctop/common/module/controller/OauthConfigController.java
  12. 1 0
      module-common/src/main/java/cn/com/ctop/common/module/entity/CtopOauthToken.java
  13. 94 0
      module-common/src/main/java/cn/com/ctop/common/module/entity/OauthConfig.java
  14. 2 0
      module-common/src/main/java/cn/com/ctop/common/module/mapper/MaterialCutFrameMapper.java
  15. 23 0
      module-common/src/main/java/cn/com/ctop/common/module/mapper/OauthConfigMapper.java
  16. 2 1
      module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/CtopOauthTokenMapper.xml
  17. 28 0
      module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/MaterialCutFrameMapper.xml
  18. 19 0
      module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/OauthConfigMapper.xml
  19. 4 1
      module-common/src/main/java/cn/com/ctop/common/module/service/IBindAccountAuthService.java
  20. 1 1
      module-common/src/main/java/cn/com/ctop/common/module/service/ICtopOauthTokenService.java
  21. 9 0
      module-common/src/main/java/cn/com/ctop/common/module/service/IMaterialCutFrameService.java
  22. 19 0
      module-common/src/main/java/cn/com/ctop/common/module/service/IOauthConfigService.java
  23. 21 15
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/BindAccountAuthServiceImpl.java
  24. 4 10
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/CtopOauthTokenServiceImpl.java
  25. 9 7
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/MaterialCutFrameServiceImpl.java
  26. 52 0
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/OauthConfigServiceImpl.java
  27. 9 1
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/RefreshTokenServiceImpl.java
  28. 16 0
      module-common/src/main/java/cn/com/ctop/common/module/utils/KuaishouInterfaceConstant.java
  29. 50 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BaseReportVideoDailyLoadJob.java
  30. 1 1
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMaterialsLoadJob.java
  31. 30 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ETLReportVideoCleanJob.java
  32. 22 1
      module-job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouAlarmRuleJob.java
  33. 4 0
      module-job-kuaishou/src/main/resources/application-jiaoyang.yml
  34. 278 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/controller/AiKuaiShouAppInfoController.java
  35. 142 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/controller/KuaiShouCreativeRefusalController.java
  36. 120 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/entity/AiKuaiShouAppInfo.java
  37. 52 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/entity/KuaishouAccountCreativeOverrunInfo.java
  38. 15 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/AiKuaiShouAppInfoMapper.java
  39. 14 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/KuaishouAccountCreativeOverrunInfoMapper.java
  40. 5 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/xml/AiKuaiShouAppInfoMapper.xml
  41. 5 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/xml/KuaishouAccountCreativeOverrunInfoMapper.xml
  42. 17 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/IAiKuaiShouAppInfoService.java
  43. 20 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/IKuaishouAccountCreativeOverrunInfoService.java
  44. 151 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/AiKuaiShouAppInfoServiceImpl.java
  45. 20 5
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/AiKuaishouNewCreateCampaignServiceImpl.java
  46. 22 8
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/KuaiShouCreateServiceImpl.java
  47. 90 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/KuaishouAccountCreativeOverrunInfoServiceImpl.java
  48. 1 1
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/KuaiShouInterfaceController.java
  49. 34 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/KuaishouTemplateController.java
  50. 1 58
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/MaterialRefuseController.java
  51. 0 4
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaiShouVideoGet.java
  52. 2 1
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouStrategy.java
  53. 2 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaiShouCreativeMapper.java
  54. 1 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaiShouVideoGetMapper.java
  55. 7 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaiShouCreativeMapper.xml
  56. 1 1
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaiShouGroupTemplateMapper.xml
  57. 6 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaiShouVideoGetMapper.xml
  58. 2 2
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouStrategyMapper.xml
  59. 9 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaiShouCreativeService.java
  60. 3 12
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouInterfaceService.java
  61. 0 1
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouTemplateService.java
  62. 91 3
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouCreativeServiceImpl.java
  63. 18 18
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouUpdateServiceImpl.java
  64. 1 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouBatchCreativePreviewServiceImpl.java
  65. 21 12
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouInterfaceServiceImpl.java
  66. 11 6
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouTemplateServiceImpl.java
  67. 1 2
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouVideoRelateCreativesServiceImpl.java
  68. 330 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/controller/KuaishouGroupExploreController.java
  69. 112 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouGroupExplore.java
  70. 2 2
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouReportDailyAgent.java
  71. 17 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/KuaishouGroupExploreMapper.java
  72. 14 14
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaiShouDailyAgentMapper.xml
  73. 5 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaishouGroupExploreMapper.xml
  74. 23 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/IKuaishouGroupExploreService.java
  75. 221 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouGroupExploreServiceImpl.java
  76. 196 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/entity/BaseReportBytedanceVideoDaily.java
  77. 436 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/entity/ETLReportBytedanceVideo.java
  78. 11 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/BaseReportBytedanceVideoDailyMapper.java
  79. 29 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/ETLReportBytedanceVideoMapper.java
  80. 5 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/xml/BaseReportBytedanceVideoDailyMapper.xml
  81. 79 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/xml/ETLReportBytedanceVideoMapper.xml
  82. 11 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/IBaseReportBytedanceVideoDailyService.java
  83. 17 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/IETLReportBytedanceVideoService.java
  84. 15 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/impl/BaseReportBytedanceVideoDailyServiceImpl.java
  85. 95 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/impl/ETLReportBytedanceVideoServiceImpl.java
  86. 25 43
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/mapper/xml/BytedanceVideoReportMapper.xml
  87. 3 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/IBytedanceVideoReportService.java
  88. 0 5
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/BytedanceReportServiceImpl.java
  89. 66 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/BytedanceVideoReportServiceImpl.java
  90. 3 3
      module-toutiao/src/main/resources/json_template/bytedance_video_report_mapping.json

+ 2 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java

@@ -184,7 +184,9 @@ public class ShiroConfig {
         filterChainDefinitionMap.put("/kuaishou/material/*", "anon");
         filterChainDefinitionMap.put("/kuaishou/create/*", "anon");
         filterChainDefinitionMap.put("/template/**", "anon");
+        filterChainDefinitionMap.put("/batch/kuaiShouGroupTemplate/*", "anon");
         filterChainDefinitionMap.put("/kuaishouBatch/**", "anon");
+        filterChainDefinitionMap.put("/kuaishou/creative/*", "anon");
 
         // 添加自己的过滤器并且取名为jwt
         Map<String, Filter> filterMap = new HashMap<>(1);

+ 1 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/BindAccountAuthController.java

@@ -54,10 +54,8 @@ public class BindAccountAuthController {
             }
 
             String authorizationType = json.getString("authorizationType");
-            // 0 三方代理商 1 本代理商
-            Integer agentType = json.getInteger("agentType");
             if ("kuaishou".equals(authorizationType)) {
-                codeUrl = bindAccountAuthService.getKuaishouCodeUrl(json.toJSONString(), agentType);
+                codeUrl = bindAccountAuthService.getKuaishouCodeUrl(json);
             }
             if ("bytedance".equals(authorizationType)) {
                 codeUrl = bindAccountAuthService.getByteDanceCodeUrl(json.toJSONString());

+ 2 - 2
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/BytedanceVideoEtlInfoController.java

@@ -83,7 +83,7 @@ public class BytedanceVideoEtlInfoController {
 				if(null!=endDate&&!"".equals(endDate.trim())){
 					queryWrapper.le("faddish_date",endDate);
 				}
-				queryWrapper.le("faddish_day_num",30);
+				queryWrapper.le("faddish_day_num",14);
 			}else {
 				//上线
 				if(null!=startDate&&!"".equals(startDate.trim())){
@@ -195,7 +195,7 @@ public class BytedanceVideoEtlInfoController {
 			  if(null!=endDate&&!"".equals(endDate.trim())){
 				  queryWrapper.le("faddish_date",endDate);
 			  }
-			  queryWrapper.le("faddish_day_num",30);
+			  queryWrapper.le("faddish_day_num",14);
 		  }else {
 			  //上线
 			  if(null!=startDate&&!"".equals(startDate.trim())){

+ 9 - 10
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CallbackController.java

@@ -119,8 +119,9 @@ public class CallbackController {
             log.info("快手授权返回信息:{}", json);
             log.info("快手授权返回oauthCode:{}", authCode);
             Integer agentType = json.getInteger("agentType");
+            Long appId = json.getLong("appId");
             if (StringUtils.isNotBlank(authCode)) {
-                KuaishouResultToken accessToken = kuaishouInterfaceService.getAccessToken(authCode, agentType);
+                KuaishouResultToken accessToken = kuaishouInterfaceService.getAccessToken(authCode, appId);
                 if (accessToken.getCode() != 0) {
                     throw new Exception("快手回调token返回错误");
                 }
@@ -131,11 +132,14 @@ public class CallbackController {
                         return "授权绑定失败!";
                     }
 
+                    Map<String, Object> advertiseBaseInfoMap = kuaishouInterfaceService.advertiserInfo(accountId, token.getAccessToken());
+                    if ((Integer) advertiseBaseInfoMap.get("code") != 0) {
+                        return "授权绑定失败,失败原因:" + advertiseBaseInfoMap.get("message");
+                    }
                     String advertiserId = json.getString("advertiserId");
                     //指定分配人姓名
                     String userName = json.getString("userName");
-                    // 广告主名称
-                    String advertiserName = json.getString("advertiser_name");
+
                     // 媒体类型: 1 头条 2 快手
                     String mediaId = json.getString("mediaId");
                     //创建人
@@ -147,6 +151,7 @@ public class CallbackController {
 
                     CtopOauthToken topOauthToken = new CtopOauthToken();
                     topOauthToken.setId(String.valueOf(accountId));
+                    topOauthToken.setAppId(json.getLong("appId"));
                     topOauthToken.setAccountId(accountId);
                     topOauthToken.setMediaId("2");
                     topOauthToken.setAdvertiserId(advertiserId);
@@ -162,8 +167,6 @@ public class CallbackController {
                     topOauthToken.setRefreshTokenExpiresIn(refreshTokenExpireInDate);
                     topOauthToken.setUpdateTime(new Date());
                     ctopOauthTokenService.saveOrUpdate(topOauthToken);
-
-
                     QueryWrapper<UserAllocation> userAllocationQueryWrapper = new QueryWrapper<>();
                     userAllocationQueryWrapper.eq("account_id", accountId);
                     userAllocationQueryWrapper.eq("media_id", 2);
@@ -179,10 +182,7 @@ public class CallbackController {
                     userAllocation.setAdvertiserId(advertiserId);
                     userAllocation.setSystemType(systemType);
                     // 获取快手昵称
-                    Map<String, Object> advertiseBaseInfoMap = kuaishouInterfaceService.advertiserInfo(accountId, token.getAccessToken());
-                    if ((Integer) advertiseBaseInfoMap.get("code") == 0) {
-                        userAllocation.setAuthName((String) advertiseBaseInfoMap.get("userName"));
-                    }
+                    userAllocation.setAuthName((String) advertiseBaseInfoMap.get("userName"));
                     userAllocation.setMediaId(mediaId);
                     userAllocation.setAccountId(accountId);
                     userAllocation.setProjectId(projectId);
@@ -199,7 +199,6 @@ public class CallbackController {
                     if (i > 0) {
                         log.info("同步分配用户表完成,task_id:{},accountId:{}", state, accountId);
                     }
-
                     //账号绑定
                     bindAccountAuthService.addBindAccount(accountId, KuaishouInterfaceConstant.LOGIN_TYPE_KUAISHOU, advertiserId);
                     Thread t = new Thread() {

+ 2 - 2
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouVideoEtlInfoController.java

@@ -80,7 +80,7 @@ public class KuaishouVideoEtlInfoController {
 				if(null!=endDate&&!"".equals(endDate.trim())){
 					queryWrapper.le("faddish_date",endDate);
 				}
-				queryWrapper.le("faddish_day_num",30);
+				queryWrapper.le("faddish_day_num",14);
 			}else {
 				//上线
 				if(null!=startDate&&!"".equals(startDate.trim())){
@@ -192,7 +192,7 @@ public class KuaishouVideoEtlInfoController {
 			  if(null!=endDate&&!"".equals(endDate.trim())){
 				  queryWrapper.le("faddish_date",endDate);
 			  }
-			  queryWrapper.lt("faddish_day_num",30);
+			  queryWrapper.lt("faddish_day_num",14);
 		  }else {
 			  //上线
 			  if(null!=startDate&&!"".equals(startDate.trim())){

+ 3 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/MaterialCutFrameController.java

@@ -5,6 +5,9 @@ import cn.com.ctop.common.module.entity.MaterialCutFrame;
 import cn.com.ctop.common.module.service.IMaterialCutFrameService;
 import cn.com.ctop.common.module.service.IMaterialCutFrameTaskService;
 import cn.com.ctop.common.module.service.IMaterialInfoService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

+ 151 - 33
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TestController.java

@@ -2,6 +2,7 @@ package org.jeecg.modules.ctop.controller;
 
 import cn.com.ctop.common.module.entity.*;
 import cn.com.ctop.common.module.mapper.CtopOauthTokenMapper;
+import cn.com.ctop.common.module.mapper.UserAllocationMapper;
 import cn.com.ctop.common.module.service.*;
 import cn.com.ctop.common.module.utils.*;
 import cn.com.ctop.common.module.vo.ResFileDTO;
@@ -11,6 +12,8 @@ import cn.com.ctop.crawler.modules.douyin.service.DouyinMusicService;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouTemplate;
 import cn.com.ctop.kuaishou.modules.batch.service.*;
 import cn.com.ctop.kuaishou.modules.graphql.service.IKuaishouWebInterfaceService;
+import cn.com.ctop.kuaishou.modules.material.entity.KuaishouAccessToken;
+import cn.com.ctop.kuaishou.modules.material.entity.KuaishouResultToken;
 import cn.com.ctop.kuaishou.modules.report.service.IKuaiShouDailyAgentService;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertiserDataService;
 import cn.com.ctop.toutiao.modules.material.service.IBytedanceEffectVideoInfoService;
@@ -29,11 +32,15 @@ import org.quartz.JobExecutionException;
 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.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.InputStream;
+import java.math.BigDecimal;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -63,8 +70,6 @@ public class TestController {
     @Autowired
     private IKuaishouWebInterfaceService kuaishouWebInterfaceService;
     @Autowired
-    private CtopOauthTokenMapper oauthTokenMapper;
-    @Autowired
     private IKuaiShouHistoryReportTaskService historyReportTaskService;
     @Autowired
     private IMaterialInfoService materialInfoService;
@@ -77,8 +82,6 @@ public class TestController {
     @Autowired
     private IMaterialImageInfoService iMaterialImageInfoService;
     @Autowired
-    private IBytedanceReportService bytedanceReportService;
-    @Autowired
     private IKuaishouInterfaceService2 kuaishouInterfaceService2;
     @Autowired
     private IUserAllocationService userAllocationService;
@@ -102,18 +105,133 @@ public class TestController {
     private IBytedanceAccountReportTaskRecordService reportTaskRecordService;
     @Resource
     private BytedanceReportMaterialDailyMapper bytedanceReportMaterialDailyMapper;
+    @Autowired
+    private ICtopOauthTokenService ctopOauthTokenService;
+
+    @Autowired
+    private IBindAccountAuthService bindAccountAuthService;
+    @Autowired
+    private UserAllocationMapper allocationMapper;
+
+    @GetMapping("/testKuaishou")
+    public String kuaishouCallback( @RequestParam("auth_code") String authCode, @RequestParam("state") String state) {
+        try {
+            JSONObject json = JSONObject.parseObject(state);
+            if (Check.isNull(json)) {
+                throw new Exception("回调信息为空");
+            }
+            log.info("快手授权返回信息:{}", json);
+            log.info("快手授权返回oauthCode:{}", authCode);
+            Integer agentType = json.getInteger("agentType");
+            Long appId = json.getLong("appId");
+            if (org.apache.commons.lang.StringUtils.isNotBlank(authCode)) {
+                KuaishouResultToken accessToken = kuaishouInterfaceService.getAccessToken(authCode, appId);
+                if (accessToken.getCode() != 0) {
+                    throw new Exception("快手回调token返回错误");
+                }
+                KuaishouAccessToken token = accessToken.getData();
+                if (token != null) {
+                    Long accountId = token.getAccountId();
+                    if (Check.isNull(accountId)) {
+                        return "授权绑定失败!";
+                    }
+                    Map<String, Object> advertiseBaseInfoMap = kuaishouInterfaceService.advertiserInfo(accountId, token.getAccessToken());
+                    if ((Integer) advertiseBaseInfoMap.get("code") != 0) {
+                        return "授权绑定失败,失败原因:" + advertiseBaseInfoMap.get("message");
+                    }
+                    String advertiserId = json.getString("advertiserId");
+                    //指定分配人姓名
+                    String userName = json.getString("userName");
+                    // 媒体类型: 1 头条 2 快手
+                    String mediaId = json.getString("mediaId");
+                    //创建人
+                    String userId = json.getString("userId");
+                    Long projectId = json.getLong("projectId");
+                    BigDecimal warningProportion = json.getBigDecimal("WarningProportion");
+                    BigDecimal warningAmount = json.getBigDecimal("WarningAmount");
+                    String systemType = json.getString("systemType");
+                    CtopOauthToken topOauthToken = new CtopOauthToken();
+                    topOauthToken.setId(String.valueOf(accountId));
+                    topOauthToken.setAppId(json.getLong("appId"));
+                    topOauthToken.setAccountId(accountId);
+                    topOauthToken.setMediaId("2");
+                    topOauthToken.setAdvertiserId(advertiserId);
+                    topOauthToken.setAgentType(agentType);
+                    topOauthToken.setAccessToken(token.getAccessToken());
+                    long accessTokenExpireIn = token.getAccessTokenExpiresIn() * 1000L;
+                    long now = System.currentTimeMillis();
+                    Date accessTokenExpireInDate = new Date(now + accessTokenExpireIn);
+                    topOauthToken.setAccessTokenExpiresIn(accessTokenExpireInDate);
+                    topOauthToken.setRefreshToken(token.getRefreshToken());
+                    long refreshTokenExpireIn = token.getRefreshTokenExpiresIn() * 1000L;
+                    Date refreshTokenExpireInDate = new Date(now + refreshTokenExpireIn);
+                    topOauthToken.setRefreshTokenExpiresIn(refreshTokenExpireInDate);
+                    topOauthToken.setUpdateTime(new Date());
+                    ctopOauthTokenService.saveOrUpdate(topOauthToken);
+                    QueryWrapper<UserAllocation> userAllocationQueryWrapper = new QueryWrapper<>();
+                    userAllocationQueryWrapper.eq("account_id", accountId);
+                    userAllocationQueryWrapper.eq("media_id", 2);
+                    userAllocationQueryWrapper.orderByDesc("create_time");
+                    userAllocationQueryWrapper.last("limit 1");
+                    UserAllocation checkUserAllocation = allocationMapper.selectOne(userAllocationQueryWrapper);
+                    if (!Check.isNull(checkUserAllocation)) {
+                        return "授权失败,该账号已被:" + checkUserAllocation.getUserName() + " 绑定!";
+                    }
+                    UserAllocation userAllocation = new UserAllocation();
+                    userAllocation.setUserName(userName);
+                    userAllocation.setUserId(userId);
+                    userAllocation.setAdvertiserId(advertiserId);
+                    userAllocation.setSystemType(systemType);
+                    // 获取快手昵称
+                    userAllocation.setAuthName((String) advertiseBaseInfoMap.get("userName"));
+                    userAllocation.setMediaId(mediaId);
+                    userAllocation.setAccountId(accountId);
+                    userAllocation.setProjectId(projectId);
+                    userAllocation.setWarningProportion(warningProportion);
+                    userAllocation.setWarningAmount(warningAmount);
+                    userAllocation.setCreateTime(new Date());
+                    userAllocation.setUpdateTime(new Date());
+                    allocationMapper.deleteById(userAllocation.getId());
+                    Map<String, Object> deleteUserMap = new HashMap<>();
+                    deleteUserMap.put("advertiser_id", advertiserId);
+                    deleteUserMap.put("account_id", accountId);
+                    allocationMapper.deleteByMap(deleteUserMap);
+                    int i = allocationMapper.insert(userAllocation);
+                    if (i > 0) {
+                        log.info("同步分配用户表完成,task_id:{},accountId:{}", state, accountId);
+                    }
+                    //账号绑定
+                    bindAccountAuthService.addBindAccount(accountId, KuaishouInterfaceConstant.LOGIN_TYPE_KUAISHOU, advertiserId);
+                    Thread t = new Thread() {
+                        @Override
+                        public void run() {
+                            try {
+                                kuaishouInterfaceService.loadKuaishouDataSingle(topOauthToken);
+                            } catch (ParseException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    };
+                    t.start();
+                }
+                return "授权绑定成功";
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "授权绑定失败!";
+    }
+
 
     @GetMapping("/getBytedanceMatReport")
     public Map<String,Object>getData(){
-        List<BytedanceAccountReportTaskRecord>  records = reportTaskRecordService.listByParams(100,"ACCOUNT_DAILY");
-        executorService = Executors.newFixedThreadPool(1);
-        CountDownLatch countDownLatch = new CountDownLatch(records.size());
-        records.forEach(record -> executorService.submit(() -> {
+        List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+        executorService = Executors.newFixedThreadPool(10);
+        CountDownLatch countDownLatch = new CountDownLatch(tokens.size());
+        tokens.forEach(record -> executorService.submit(() -> {
             try {
-//                reportService.getAdvertiserReport(record, CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
-//                log.info("账户数据获取完成:account:{},时间:{}-{}",record.getAccountId(),record.getStartDate(),record.getEndDate());
-                bytedanceReportService.bytedanceMaterialReportV2(record);
-                log.info("素材数据获取完成:account:{},时间:{}-{}",record.getAccountId(),record.getStartDate(),record.getEndDate());
+                reportService.getAdvertiserReport(record, DateUtils.parseDate("2021-01-01","yyyy-MM-dd"), DateUtils.parseDate("2021-01-31","yyyy-MM-dd"),CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
+                log.info("账户数据获取完成:account:{},时间:{}-{}",record.getAccountId(),"2021-01-01","2020-01-31");
             } catch (Exception e) {
 
             } finally {
@@ -126,11 +244,11 @@ public class TestController {
             e.printStackTrace();
         }
         System.out.println("数据获取完成");
-        bytedanceReportMaterialDailyMapper.updateImageReportCode();
-        bytedanceReportMaterialDailyMapper.updateImageReportProjectId();
-        bytedanceReportMaterialDailyMapper.updateImageReportProjectName();
-        bytedanceReportMaterialDailyMapper.updateImageReportPlaneId();
-        bytedanceReportMaterialDailyMapper.updateImageReportPlaneName();
+//        bytedanceReportMaterialDailyMapper.updateImageReportCode();
+//        bytedanceReportMaterialDailyMapper.updateImageReportProjectId();
+//        bytedanceReportMaterialDailyMapper.updateImageReportProjectName();
+//        bytedanceReportMaterialDailyMapper.updateImageReportPlaneId();
+//        bytedanceReportMaterialDailyMapper.updateImageReportPlaneName();
         Map<String,Object> result =  new HashMap<>();
         ResultMapUtils.setResultMap(new HashMap<>(),StatusCode.COMMON_SUCCESS);
         return result;
@@ -192,7 +310,7 @@ public class TestController {
                     QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
                     tokenQueryWrapper.eq("media_id", 2);
                     tokenQueryWrapper.eq("account_id", accountId);
-                    CtopOauthToken token = oauthTokenMapper.selectOne(tokenQueryWrapper);
+                    CtopOauthToken token = tokenMapper.selectOne(tokenQueryWrapper);
                     if (!Check.isNull(token)) {
                         suzhaoService.submit(new Runnable() {
                             @Override
@@ -402,7 +520,7 @@ public class TestController {
                     QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
                     tokenQueryWrapper.eq("media_id", 2);
                     tokenQueryWrapper.eq("account_id", accountId);
-                    CtopOauthToken ctopOauthTokens = oauthTokenMapper.selectOne(tokenQueryWrapper);
+                    CtopOauthToken ctopOauthTokens = tokenMapper.selectOne(tokenQueryWrapper);
                     if (!Check.isNull(ctopOauthTokens)) {
                         historyReportTaskService.createTask(ctopOauthTokens.getAccountId(), ctopOauthTokens.getAccessToken(), startDate, endDate, CtopAdConstant.KUAISHOU_LOAD_JOB_TYPE_DAILY);
 
@@ -435,7 +553,7 @@ public class TestController {
                     QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
                     tokenQueryWrapper.eq("media_id", 2);
                     tokenQueryWrapper.eq("account_id", accountId);
-                    CtopOauthToken ctopOauthTokens = oauthTokenMapper.selectOne(tokenQueryWrapper);
+                    CtopOauthToken ctopOauthTokens = tokenMapper.selectOne(tokenQueryWrapper);
                     if (!Check.isNull(ctopOauthTokens)) {
                         historyReportTaskService.createTask(ctopOauthTokens.getAccountId(), ctopOauthTokens.getAccessToken(), startDate, endDate, CtopAdConstant.KUAISHOU_LOAD_JOB_TYPE_HISTORY);
 
@@ -462,7 +580,7 @@ public class TestController {
             QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
             tokenQueryWrapper.eq("media_id", 2);
             tokenQueryWrapper.eq("account_id", accountId);
-            CtopOauthToken ctopOauthTokens = oauthTokenMapper.selectOne(tokenQueryWrapper);
+            CtopOauthToken ctopOauthTokens = tokenMapper.selectOne(tokenQueryWrapper);
             if (!Check.isNull(ctopOauthTokens)) {
                 historyReportTaskService.createTask(ctopOauthTokens.getAccountId(), ctopOauthTokens.getAccessToken(), statDate, statDate, CtopAdConstant.KUAISHOU_LOAD_JOB_TYPE_DAILY);
 
@@ -710,11 +828,11 @@ public class TestController {
     }
 
 
-    @GetMapping(value = "/getToken")
+   /* @GetMapping(value = "/getToken")
     public String getToken(Long accountId, String token, String refreshToken, Integer agentType) {
         oauthTokenService.getKuaiShouRefreshToken(accountId, token, refreshToken, agentType);
         return "Success";
-    }
+    }*/
 
 
     @GetMapping(value = "/getAccountReport")
@@ -723,7 +841,7 @@ public class TestController {
         oauthTokenQueryWrapper.eq("media_id", 2);
         oauthTokenQueryWrapper.eq("account_id", accountId);
         oauthTokenQueryWrapper.last("limit 1");
-        CtopOauthToken token = oauthTokenMapper.selectOne(oauthTokenQueryWrapper);
+        CtopOauthToken token = tokenMapper.selectOne(oauthTokenQueryWrapper);
         SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd");
         Date date1 = sim.parse(startDate);
         Date date2 = sim.parse(endDate);
@@ -741,7 +859,7 @@ public class TestController {
             Date date2 = sim.parse(endDate);
             QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
             tokenQueryWrapper.eq("media_id", 2);
-            List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(tokenQueryWrapper);
+            List<CtopOauthToken> ctopOauthTokens = tokenMapper.selectList(tokenQueryWrapper);
             if (!Check.isNull(ctopOauthTokens)) {
                 for (CtopOauthToken token : ctopOauthTokens) {
                     kuaishouInterfaceService.getAdvertiserReportDaily(token, date1, date2);
@@ -819,7 +937,7 @@ public class TestController {
             oauthTokenQueryWrapper.eq("media_id", 2);
             oauthTokenQueryWrapper.eq("account_id", accountId);
             oauthTokenQueryWrapper.last("limit 1");
-            CtopOauthToken token = oauthTokenMapper.selectOne(oauthTokenQueryWrapper);
+            CtopOauthToken token = tokenMapper.selectOne(oauthTokenQueryWrapper);
             String endDateStr = DateUtils.getDate("yyyy-MM-dd");
             String startDate = DateUtils.addMonth(endDateStr, -6);
             historyReportTaskService.createTask(token.getAccountId(), token.getAccessToken(), startDate, endDateStr, CtopAdConstant.KUAISHOU_LOAD_JOB_TYPE_HISTORY);
@@ -840,7 +958,7 @@ public class TestController {
             String startDate = DateUtils.addMonth(endDateStr, -6);
             QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
             tokenQueryWrapper.eq("media_id", 2);
-            List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(tokenQueryWrapper);
+            List<CtopOauthToken> ctopOauthTokens = tokenMapper.selectList(tokenQueryWrapper);
             if (!Check.isNull(ctopOauthTokens)) {
                 for (CtopOauthToken token : ctopOauthTokens) {
                     historyReportTaskService.createTask(token.getAccountId(), token.getAccessToken(), "2020-09-01", "2020-10-01", CtopAdConstant.KUAISHOU_LOAD_JOB_TYPE_HISTORY);
@@ -864,7 +982,7 @@ public class TestController {
             QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
             tokenQueryWrapper.eq("media_id", 2);
             tokenQueryWrapper.eq("account_id", accountId);
-            CtopOauthToken ctopOauthTokens = oauthTokenMapper.selectOne(tokenQueryWrapper);
+            CtopOauthToken ctopOauthTokens = tokenMapper.selectOne(tokenQueryWrapper);
             if (!Check.isNull(ctopOauthTokens)) {
                 historyReportTaskService.createTask(ctopOauthTokens.getAccountId(), ctopOauthTokens.getAccessToken(), startDate, endDateStr, CtopAdConstant.KUAISHOU_LOAD_JOB_TYPE_HISTORY);
 
@@ -928,7 +1046,7 @@ public class TestController {
     public void gerCreative() {
         QueryWrapper<CtopOauthToken> oauthTokenQueryWrapper = new QueryWrapper<>();
         oauthTokenQueryWrapper.eq("media_id", 2);
-        List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(oauthTokenQueryWrapper);
+        List<CtopOauthToken> ctopOauthTokens = tokenMapper.selectList(oauthTokenQueryWrapper);
         for (CtopOauthToken token : ctopOauthTokens) {
             executorService.submit(new Runnable() {
                 @Override
@@ -1001,7 +1119,7 @@ public class TestController {
         oauthTokenQueryWrapper.eq("media_id", 2);
         oauthTokenQueryWrapper.eq("account_id", accountId);
         oauthTokenQueryWrapper.last("limit 1");
-        CtopOauthToken token = oauthTokenMapper.selectOne(oauthTokenQueryWrapper);
+        CtopOauthToken token = tokenMapper.selectOne(oauthTokenQueryWrapper);
         try {
             // kuaishouInterfaceService.getCampaignList(token, null, null);
             //1:获取全量广告组数据
@@ -1054,7 +1172,7 @@ public class TestController {
         oauthTokenQueryWrapper.eq("media_id", 2);
         oauthTokenQueryWrapper.eq("account_id", accountId);
         oauthTokenQueryWrapper.last("limit 1");
-        CtopOauthToken token = oauthTokenMapper.selectOne(oauthTokenQueryWrapper);
+        CtopOauthToken token = tokenMapper.selectOne(oauthTokenQueryWrapper);
         executorService.submit(new Runnable() {
             @Override
             public void run() {
@@ -1088,7 +1206,7 @@ public class TestController {
 
             QueryWrapper<CtopOauthToken> oauthTokenQueryWrapper = new QueryWrapper<>();
             oauthTokenQueryWrapper.eq("media_id", 2);
-            List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(oauthTokenQueryWrapper);
+            List<CtopOauthToken> ctopOauthTokens = tokenMapper.selectList(oauthTokenQueryWrapper);
 
             if (!Check.isNull(ctopOauthTokens)) {
                 for (CtopOauthToken token : ctopOauthTokens) {
@@ -1118,7 +1236,7 @@ public class TestController {
 
             QueryWrapper<CtopOauthToken> oauthTokenQueryWrapper = new QueryWrapper<>();
             oauthTokenQueryWrapper.eq("media_id", 2);
-            List<CtopOauthToken> ctopOauthTokens = oauthTokenMapper.selectList(oauthTokenQueryWrapper);
+            List<CtopOauthToken> ctopOauthTokens = tokenMapper.selectList(oauthTokenQueryWrapper);
             if (!Check.isNull(ctopOauthTokens)) {
                 for (CtopOauthToken token : ctopOauthTokens) {
                     executorService.submit(new Runnable() {

+ 1 - 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/orderplatform/mapper/xml/PlatformScriptMapper.xml

@@ -8,7 +8,7 @@
             t1.`name`,
             t1.size,
             t1.create_time,
-            FROM_UNIXTIME(CAST(t1.create_time/1000 AS INT)) as createTime,
+        FROM_UNIXTIME(ROUND((t1.create_time/1000),0)) as createTime,
             (SELECT realname from sys_user where id=t1.creator limit 1) as creatorName,
             (SELECT project_name from ctop_project where id=t1.project_id limit 1) as projectName,
             t2.material_name as materialName

+ 24 - 11
jeecg-boot-module-system/src/main/resources/application-jiaoyang.yml

@@ -1,5 +1,5 @@
 server:
-  port: 8804
+  port: 8805
   ip: 39.97.120.42
   servlet:
     context-path: /jeecg-boot
@@ -28,8 +28,8 @@ spring:
           starttls:
             enable: true
             required: true
-  ## quartz定时任务,采用数据库方式
-  #quartz:
+    ## quartz定时任务,采用数据库方式
+    #quartz:
     #job-store-type: jdbc
   #json 时间戳统一转换
   jackson:
@@ -67,14 +67,14 @@ spring:
   autoconfigure:
     exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
   datasource:
-    url: jdbc:mysql://172.30.0.4:4000/jiaoyang?characterEncoding=UTF-8&useUnicode=true&useSSL=false
+    url: jdbc:mysql://172.30.0.4:4000/jiaoyang?characterEncoding=UTF-8&useUnicode=true&allowMultiQueries=true&useSSL=false
     username: hcst
     password: hcst@2020
     driver-class-name: com.mysql.jdbc.Driver
     druid:
       stat-view-servlet:
         loginUsername: admin
-        loginPassword: hcst20161
+        loginPassword: hcst2016
         enabled: true
       web-stat-filter:
         enabled: true
@@ -106,10 +106,16 @@ spring:
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master:
-          url: jdbc:mysql://172.30.0.4:4000/jiaoyang?characterEncoding=UTF-8&useUnicode=true&useSSL=false
+          url: jdbc:mysql://172.30.0.4:4000/jiaoyang?characterEncoding=UTF-8&useUnicode=true&allowMultiQueries=true&useSSL=false
           username: hcst
           password: hcst@2020
           driver-class-name: com.mysql.jdbc.Driver
+          # 多数据源配置
+          #multi-datasource1:
+          #url: jdbc:mysql://localhost:3306/jeecg-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
+          #username: root
+          #password: root
+          #driver-class-name: com.mysql.jdbc.Driver
   #redis 配置
   redis:
     database: 0
@@ -138,6 +144,13 @@ mybatis-plus:
 #    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 #jeecg专用配置
 jeecg:
+  #积木报表设置
+  jmreport:
+    mode: dev
+    #是否需要校验token
+    is_verify_token: false
+    #必须校验方法
+    verify_methods: remove,delete,save,add,update
   elasticsearch:
     cluster-nodes:
     check-enabled: false
@@ -175,12 +188,12 @@ jeecg:
 kuaishou:
   api-url: https://ad.e.kuaishou.com
   auth-url: https://ad.e.kuaishou.com
-  appid: 328
+  appid: 27
   third-appid: 328
   oauth-type: agent
-  secret: 1iFTBiMdohkyEQQs
+  secret: QovprB1tNhXptgDc
   third-secret: 1iFTBiMdohkyEQQs
-  callback-url: http://callback.shyouteng.com.cn/kuaishou
+  callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/kuaishou
   third-callback-url: http://callback.shyouteng.com.cn/kuaishou
   apk-sava-path: /mnt/file/apk
   image-sava-path: /mnt/file/image
@@ -246,5 +259,5 @@ bytedance:
     advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/
 ai:
   callback:
-    callback-unit-url: http://192.168.1.193:31012/ai_callback_add_group
-    callback-creative-url: http://192.168.1.193:31012/ai_callback_add_creative
+    callback-unit-url: http://139.186.27.96:31012/ai_callback_add_group
+    callback-creative-url: http://139.186.27.96:31012/ai_callback_add_creative

+ 81 - 10
jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java

@@ -20,6 +20,7 @@ import cn.com.ctop.kuaishou.modules.report.service.IRuleKuaiShouPlanService;
 import cn.com.ctop.oa.modules.service.IWechatCheckinDataService;
 import cn.com.ctop.oa.modules.service.IWechatNoListService;
 import cn.com.ctop.oa.modules.service.IWechatUserListService;
+import cn.com.ctop.toutiao.modules.link.service.IETLReportBytedanceVideoService;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertiserDataService;
 import cn.com.ctop.toutiao.modules.report.entity.BytedanceAccountReportTaskRecord;
 import cn.com.ctop.toutiao.modules.report.mapper.BytedanceReportMaterialDailyMapper;
@@ -394,15 +395,16 @@ public class SampleTest {
 
     @Autowired
     private IBytedanceAccountReportTaskRecordService reportTaskRecordService;
+
     @Test
     public void execute() {
-        List<UserAllocation>  allocations = allocationService.listByMediaId("3",0);
-        for (UserAllocation allocation:allocations) {
-            BytedanceAccountReportTaskRecord reportTaskRecord1 = new BytedanceAccountReportTaskRecord(allocation.getAccountId(),"2020-10-01","2020-10-31");
+        List<UserAllocation> allocations = allocationService.listByMediaId("3", 0);
+        for (UserAllocation allocation : allocations) {
+            BytedanceAccountReportTaskRecord reportTaskRecord1 = new BytedanceAccountReportTaskRecord(allocation.getAccountId(), "2020-10-01", "2020-10-31");
             reportTaskRecordService.save(reportTaskRecord1);
-            BytedanceAccountReportTaskRecord reportTaskRecord2 = new BytedanceAccountReportTaskRecord(allocation.getAccountId(),"2020-11-01","2020-11-30");
+            BytedanceAccountReportTaskRecord reportTaskRecord2 = new BytedanceAccountReportTaskRecord(allocation.getAccountId(), "2020-11-01", "2020-11-30");
             reportTaskRecordService.save(reportTaskRecord2);
-            BytedanceAccountReportTaskRecord reportTaskRecord3 = new BytedanceAccountReportTaskRecord(allocation.getAccountId(),"2020-12-01","2020-12-31");
+            BytedanceAccountReportTaskRecord reportTaskRecord3 = new BytedanceAccountReportTaskRecord(allocation.getAccountId(), "2020-12-01", "2020-12-31");
             reportTaskRecordService.save(reportTaskRecord3);
         }
     }
@@ -507,17 +509,86 @@ public class SampleTest {
 //                aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2,50);
 //            }
 //        }
-
-        AiKuaishouAccountTargetTemplate accountTargetTemplate2 = aiKuaishouAccountTargetTemplateService.getById(120001);
-        aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2,1);
+        /**
+         * 120002
+         * 150001
+         * 150002
+         * 150003
+         * 150004
+         */
+
+        AiKuaishouAccountTargetTemplate accountTargetTemplate2 = aiKuaishouAccountTargetTemplateService.getById(120002);
+        aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2, 250);
+        accountTargetTemplate2 = aiKuaishouAccountTargetTemplateService.getById(150001);
+        aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2, 250);
+        accountTargetTemplate2 = aiKuaishouAccountTargetTemplateService.getById(150002);
+        aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2, 250);
+        accountTargetTemplate2 = aiKuaishouAccountTargetTemplateService.getById(150003);
+        aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2, 250);
+        accountTargetTemplate2 = aiKuaishouAccountTargetTemplateService.getById(150004);
+        aiKuaishouNewCreateCampaign.kuaishouAiAddNewMaterialCreativity(accountTargetTemplate2, 250);
     }
 
     @Autowired
     private IBytedancePlanDailyReportService planDailyReportService;
 
     @Test
-    public void etlKuaishouProjectData(){
+    public void etlKuaishouProjectData() {
         CtopOauthToken token = tokenService.getTokenByAccountId(1660666858777607L);
-        reportService.getAdvertiserPlanReport(token,DateUtils.parseDate("2021-01-25","yyyy-MM-dd"),DateUtils.parseDate("2021-01-25","yyyy-MM-dd"),CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
+        reportService.getAdvertiserPlanReport(token, DateUtils.parseDate("2021-01-25", "yyyy-MM-dd"), DateUtils.parseDate("2021-01-25", "yyyy-MM-dd"), CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
+    }
+
+    @Autowired
+    IBytedanceVideoReportService bytedanceVideoReportService;
+
+    @Test
+    public void etlBytedanceVideoReport() {
+
+        for (int i = 1; i <= 62; i++) {
+            etlBytedanceVideo(DateUtils.formatDate(DateUtils.addDay(new Date(), -i)));
+        }
+        //etlBytedanceVideo("2021-02-01");
+
+    }
+
+    private void etlBytedanceVideo(String statDate) {
+        List<CtopOauthToken> tokens = oauthTokenService.selectToutiaoToken();
+        executorService = Executors.newFixedThreadPool(30);
+        countDownLatch = new CountDownLatch(tokens.size());
+        tokens.forEach(token -> executorService.submit(() -> {
+            try {
+                bytedanceVideoReportService.pullVideoReport(token, statDate, statDate, 1);
+            } catch (Exception e) {
+
+            } finally {
+                countDownLatch.countDown();
+            }
+        }));
+        try {
+            countDownLatch.await();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Autowired
+    IETLReportBytedanceVideoService ietlReportBytedanceVideoService;
+
+    @Test
+    public void etlBytedanceVideoReportClean() {
+        for (int i = 1; i <= 1; i++) {
+            String statDate = DateUtils.formatDate(DateUtils.addDay(new Date(), -i));
+            ietlReportBytedanceVideoService.cleanETL(statDate);
+        }
+    }
+
+    @Test
+    public void etlBytedanceVideoReportClean1() {
+        //executorService = Executors.newFixedThreadPool(31);
+        //countDownLatch = new CountDownLatch(31);
+        for (int i = 3; i <= 31; i++) {
+            String statDate = DateUtils.formatDate(DateUtils.addDay(new Date(), -i));
+                    ietlReportBytedanceVideoService.cleanETL(statDate);
+        }
     }
 }

+ 246 - 0
module-common/src/main/java/cn/com/ctop/common/module/controller/OauthConfigController.java

@@ -0,0 +1,246 @@
+package cn.com.ctop.common.module.controller;
+
+import cn.com.ctop.common.module.annotation.AutoLog;
+import cn.com.ctop.common.module.entity.OauthConfig;
+import cn.com.ctop.common.module.service.IOauthConfigService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 授权配置信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-01-26
+ */
+@Slf4j
+@Api(tags = "授权配置信息")
+@RestController
+@RequestMapping("/auth/oauthConfig")
+public class OauthConfigController {
+    @Autowired
+    private IOauthConfigService oauthConfigService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param oauthConfig
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "授权配置信息-分页列表查询")
+    @ApiOperation(value = "授权配置信息-分页列表查询", notes = "授权配置信息-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<List<OauthConfig>> queryPageList(OauthConfig oauthConfig,
+                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                   HttpServletRequest req) {
+        Result<List<OauthConfig>> result = new Result<>();
+        QueryWrapper<OauthConfig> queryWrapper = QueryGenerator.initQueryWrapper(oauthConfig, req.getParameterMap());
+        queryWrapper.orderByAsc("agent_rank");
+        List<OauthConfig> pageList = oauthConfigService.list(queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param oauthConfig
+     * @return
+     */
+    @AutoLog(value = "授权配置信息-添加")
+    @ApiOperation(value = "授权配置信息-添加", notes = "授权配置信息-添加")
+    @PostMapping(value = "/add")
+    public Result<OauthConfig> add(@RequestBody OauthConfig oauthConfig) {
+        Result<OauthConfig> result = new Result<>();
+        try {
+            oauthConfigService.save(oauthConfig);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param oauthConfig
+     * @return
+     */
+    @AutoLog(value = "授权配置信息-编辑")
+    @ApiOperation(value = "授权配置信息-编辑", notes = "授权配置信息-编辑")
+    @PutMapping(value = "/edit")
+    public Result<OauthConfig> edit(@RequestBody OauthConfig oauthConfig) {
+        Result<OauthConfig> result = new Result<OauthConfig>();
+        OauthConfig oauthConfigEntity = oauthConfigService.getById(oauthConfig.getId());
+        if (oauthConfigEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = oauthConfigService.updateById(oauthConfig);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "授权配置信息-通过id删除")
+    @ApiOperation(value = "授权配置信息-通过id删除", notes = "授权配置信息-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            oauthConfigService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "授权配置信息-批量删除")
+    @ApiOperation(value = "授权配置信息-批量删除", notes = "授权配置信息-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<OauthConfig> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<OauthConfig> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.oauthConfigService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "授权配置信息-通过id查询")
+    @ApiOperation(value = "授权配置信息-通过id查询", notes = "授权配置信息-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<OauthConfig> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<OauthConfig> result = new Result<>();
+        OauthConfig oauthConfig = oauthConfigService.getById(id);
+        if (oauthConfig == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(oauthConfig);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<OauthConfig> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                OauthConfig oauthConfig = JSON.parseObject(deString, OauthConfig.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(oauthConfig, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<OauthConfig> pageList = oauthConfigService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "授权配置信息列表");
+        mv.addObject(NormalExcelConstants.CLASS, OauthConfig.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("授权配置信息列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<OauthConfig> listOauthConfigs = ExcelImportUtil.importExcel(file.getInputStream(), OauthConfig.class, params);
+                oauthConfigService.saveBatch(listOauthConfigs);
+                return Result.ok("文件导入成功!数据行数:" + listOauthConfigs.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 1 - 0
module-common/src/main/java/cn/com/ctop/common/module/entity/CtopOauthToken.java

@@ -76,6 +76,7 @@ public class CtopOauthToken {
 
 
     private Integer agentType;
+    private Long appId;
 
     /**
      * 刷新令牌有效期

+ 94 - 0
module-common/src/main/java/cn/com/ctop/common/module/entity/OauthConfig.java

@@ -0,0 +1,94 @@
+package cn.com.ctop.common.module.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.util.Date;
+
+/**
+ * 授权配置信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-01-26
+ */
+@Data
+@TableName("ctop_oauth_config")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_oauth_config对象", description = "授权配置信息")
+public class OauthConfig {
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+
+
+    private Integer mediaId;
+    /**
+     * 代理商名称
+     */
+    @Excel(name = "代理商名称", width = 15)
+    @ApiModelProperty(value = "代理商名称")
+    private String agentName;
+    /**
+     * appid
+     */
+    @Excel(name = "appid", width = 15)
+    @ApiModelProperty(value = "appid")
+    private Integer appId;
+    /**
+     * secret
+     */
+    @Excel(name = "secret", width = 15)
+    @ApiModelProperty(value = "secret")
+    private String secret;
+    /**
+     * 回调地址
+     */
+    @Excel(name = "回调地址", width = 15)
+    @ApiModelProperty(value = "回调地址")
+    private String redirectUri;
+
+
+    private Integer status;
+
+    private Integer oauthType;
+
+    /**
+     * 排序
+     */
+    @Excel(name = "排序", width = 15)
+    @ApiModelProperty(value = "排序")
+    private Integer agentRank;
+
+    String callbackUrl;
+    /**
+     * 创建时间
+     */
+    @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;
+}

+ 2 - 0
module-common/src/main/java/cn/com/ctop/common/module/mapper/MaterialCutFrameMapper.java

@@ -21,4 +21,6 @@ public interface MaterialCutFrameMapper extends BaseMapper<MaterialCutFrame> {
     List<MaterialCutFrame> getListByVideoSignature(@Param(value = "videoSignature") String signature);
 
     List<JSONObject> getProgramCreativeCover(@Param("signature") String signature);
+
+    JSONObject getCutFrameByVideoMd5(@Param("photoId") String photoId,@Param("imageToken") String imageToken);
 }

+ 23 - 0
module-common/src/main/java/cn/com/ctop/common/module/mapper/OauthConfigMapper.java

@@ -0,0 +1,23 @@
+package cn.com.ctop.common.module.mapper;
+
+import cn.com.ctop.common.module.entity.OauthConfig;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 授权配置信息
+ *
+ * @author: jeecg-boot
+ * @date: 2021-01-26
+ * @cersion: V1.0
+ */
+public interface OauthConfigMapper extends BaseMapper<OauthConfig> {
+
+    Map<Long, String> getConfigMapByMediaId(@Param("mediaId") int mediaId);
+
+    List<JSONObject> getListByMediaId(@Param("mediaId") int mediaId);
+}

+ 2 - 1
module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/CtopOauthTokenMapper.xml

@@ -12,12 +12,13 @@
         <result column="access_token_expires_in" property="accessTokenExpiresIn" jdbcType="TIMESTAMP"/>
         <result column="refresh_token_expires_in" property="refreshTokenExpiresIn" jdbcType="TIMESTAMP"/>
         <result column="agent_type" property="agentType" jdbcType="INTEGER"/>
+        <result column="app_id" property="appId" jdbcType="BIGINT"/>
         <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
         <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
     </resultMap>
 
     <sql id="Base_Column_List">
-        id,media_id,advertiser_id,account_id,access_token,refresh_token,access_token_expires_in,refresh_token_expires_in,agent_type,create_time,update_time
+        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
    </sql>
 
     <select id="selectByteDanceTokens" resultMap="BaseResultMap">

+ 28 - 0
module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/MaterialCutFrameMapper.xml

@@ -34,4 +34,32 @@
       ORDER BY RAND() LIMIT 5;
     </select>
 
+    <select id="getCutFrameByVideoMd5" resultType="com.alibaba.fastjson.JSONObject">
+      SELECT
+	   url as 'url',
+	   signature as 'signature'
+        FROM
+	    ctop_material_cut_frame
+        WHERE
+	video_signature = (
+		SELECT
+			signature
+		FROM
+			ctop_kuaishou_video_get
+		WHERE
+			photo_id = #{photoId}
+		LIMIT 1
+	    )
+        AND signature != (
+	SELECT
+		signature
+	FROM
+		ctop_kuaishou_image_get
+	WHERE
+		image_token = #{imageToken}
+	LIMIT 1
+        )
+        LIMIT 1
+    </select>
+
 </mapper>

+ 19 - 0
module-common/src/main/java/cn/com/ctop/common/module/mapper/xml/OauthConfigMapper.xml

@@ -0,0 +1,19 @@
+<?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.common.module.mapper.OauthConfigMapper">
+
+    <select id="getConfigMapByMediaId" resultType="map">
+       select
+       app_id,
+       secret
+       from ctop_oauth_config
+       where media_id = #{mediaId}
+    </select>
+    <select id="getListByMediaId" resultType="com.alibaba.fastjson.JSONObject">
+       select
+       app_id,
+       secret
+       from ctop_oauth_config
+       where media_id = #{mediaId}
+    </select>
+</mapper>

+ 4 - 1
module-common/src/main/java/cn/com/ctop/common/module/service/IBindAccountAuthService.java

@@ -1,6 +1,7 @@
 package cn.com.ctop.common.module.service;
 
 import cn.com.ctop.common.module.entity.BindAccountAuth;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import java.io.UnsupportedEncodingException;
@@ -20,10 +21,11 @@ public interface IBindAccountAuthService extends IService<BindAccountAuth> {
      * @return
      * @throws UnsupportedEncodingException
      */
-    String getKuaishouCodeUrl(String state,Integer  agentType ) throws UnsupportedEncodingException;
+    String getKuaishouCodeUrl(JSONObject state) throws UnsupportedEncodingException;
 
     /**
      * 获取头条url
+     *
      * @param state
      * @return
      * @throws UnsupportedEncodingException
@@ -32,6 +34,7 @@ public interface IBindAccountAuthService extends IService<BindAccountAuth> {
 
     /**
      * 绑定账号
+     *
      * @param accountId
      * @param type
      * @param state

+ 1 - 1
module-common/src/main/java/cn/com/ctop/common/module/service/ICtopOauthTokenService.java

@@ -20,7 +20,7 @@ public interface ICtopOauthTokenService extends IService<CtopOauthToken> {
 
     Map<String, Object> getByteDanceAccessToken(CtopOauthToken token);
 
-    void getKuaiShouRefreshToken(Long accountId, String token, String refreshToken, Integer agentType);
+    void getKuaiShouRefreshToken(Long accountId, String token, String refreshToken, Long appId, String secret);
 
     List<CtopOauthToken> getTokenListByType(String platformTypeBytedance);
 

+ 9 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/IMaterialCutFrameService.java

@@ -29,4 +29,13 @@ public interface IMaterialCutFrameService extends IService<MaterialCutFrame> {
     List<JSONObject> getProgramCreativeCover(String signature);
 
     MaterialCutFrame selectByMd5(String md5);
+
+    /**
+     * 根基photoId imageToken 获取单张封面
+     *
+     * @param photoId
+     * @param imageToken
+     * @return
+     */
+    JSONObject getCutFrameByVideoMd5(String photoId, String imageToken);
 }

+ 19 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/IOauthConfigService.java

@@ -0,0 +1,19 @@
+package cn.com.ctop.common.module.service;
+
+import cn.com.ctop.common.module.entity.OauthConfig;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.Map;
+
+/**
+ * @Description: 授权配置信息
+ * @Author: jeecg-boot
+ * @Date: 2021-01-26
+ * @Version: V1.0
+ */
+public interface IOauthConfigService extends IService<OauthConfig> {
+
+    OauthConfig getConfigByAppId(Long appId);
+
+    Map<Long, String> getConfigMapByMediaId(int mediaId);
+}

+ 21 - 15
module-common/src/main/java/cn/com/ctop/common/module/service/impl/BindAccountAuthServiceImpl.java

@@ -1,11 +1,14 @@
 package cn.com.ctop.common.module.service.impl;
 
 import cn.com.ctop.common.module.entity.BindAccountAuth;
+import cn.com.ctop.common.module.entity.OauthConfig;
 import cn.com.ctop.common.module.mapper.BindAccountAuthMapper;
 import cn.com.ctop.common.module.service.IBindAccountAuthService;
+import cn.com.ctop.common.module.service.IOauthConfigService;
 import cn.com.ctop.common.module.utils.BytedanceInterfaceConstant;
 import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
 import cn.com.ctop.common.module.utils.PropertiesUtils;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -64,23 +67,26 @@ public class BindAccountAuthServiceImpl extends ServiceImpl<BindAccountAuthMappe
     }
 
 
+    @Autowired
+    private IOauthConfigService oauthConfigService;
+
     @Override
-    public String getKuaishouCodeUrl(String state, Integer agentType) throws UnsupportedEncodingException {
+    public String getKuaishouCodeUrl(JSONObject state) throws UnsupportedEncodingException {
         StringBuffer sb = new StringBuffer();
-        if (agentType == 1) {
-            sb.append(PropertiesUtils.getValue("kuaishou_config", "kuaishou_auth_url"))
-                    .append(KuaishouInterfaceConstant.AUTH_PATH)
-                    .append("?app_id=" + PropertiesUtils.getValue("kuaishou_config", "kuaishou_appid"))
-                    .append("&state=" + URLEncoder.encode(URLEncoder.encode(state)))
-                    .append("&scope=%5B%22report_service%22%2C%22ad_query%22%2C%22account_service%22%2C%22ad_manage%22%5D")
-                    .append("&redirect_uri=" + URLEncoder.encode(PropertiesUtils.getValue("kuaishou_config", "kuaishou_callback_url"), "UTF-8"));
-        } else if (agentType == 0) {
-            sb.append(PropertiesUtils.getValue("kuaishou_config", "kuaishou_auth_url"))
-                    .append(KuaishouInterfaceConstant.AUTH_PATH)
-                    .append ("?app_id=" + PropertiesUtils.getValue("kuaishou_config", "kuaishou_third_appid"))
-                    .append("&state=" + URLEncoder.encode(URLEncoder.encode(state)))
-                    .append("&scope=%5B%22report_service%22%2C%22ad_query%22%2C%22account_service%22%2C%22ad_manage%22%5D")
-                    .append("&redirect_uri=" + URLEncoder.encode(PropertiesUtils.getValue("kuaishou_config", "kuaishou_third_callback_url"), "UTF-8"));
+        Long id = state.getLong("id");
+
+        OauthConfig config = oauthConfigService.getById(id);
+        state.put("appId", config.getAppId());
+        state.put("callbackUrl", config.getCallbackUrl());
+        sb.append(PropertiesUtils.getValue("kuaishou_config", "kuaishou_auth_url"))
+                .append(KuaishouInterfaceConstant.AUTH_PATH)
+                .append("?app_id=" + config.getAppId())
+                .append("&state=" + URLEncoder.encode(URLEncoder.encode(state.toJSONString())))
+                .append("&redirect_uri=" + URLEncoder.encode(config.getRedirectUri(), "UTF-8"));
+        if (config.getOauthType() != 1) {
+            sb.append("&scope=%5B%22report_service%22%2C%22ad_query%22%2C%22account_service%22%2C%22ad_manage%22%5D");
+        } else {
+            sb.append("&scope=%5B%22report_service%22%2C%22ad_query%22%2C%22ad_manage%22%5D");
         }
         return sb.toString();
     }

+ 4 - 10
module-common/src/main/java/cn/com/ctop/common/module/service/impl/CtopOauthTokenServiceImpl.java

@@ -121,20 +121,14 @@ public class CtopOauthTokenServiceImpl extends ServiceImpl<CtopOauthTokenMapper,
      * @return
      */
     @Override
-    public void getKuaiShouRefreshToken(Long accountId, String token, String refreshToken, Integer agentType) {
+    public void getKuaiShouRefreshToken(Long accountId, String token, String refreshToken, Long appId, String secret) {
         log.info("快手刷新token入参,accountId:{},token:{},refreshToken:{}", accountId, token, refreshToken);
         String url = PropertiesUtils.getConfig("kuaishou_api_url") + "/rest/openapi/oauth2/authorize/refresh_token";
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", " application/json");
         Map<String, Object> param = new HashMap<>();
-        if (agentType == 1) {
-            param.put("app_id", PropertiesUtils.getConfig("kuaishou_appid"));
-            param.put("secret", PropertiesUtils.getConfig("kuaishou_secret"));
-        } else if (agentType == 0) {
-            param.put("app_id", PropertiesUtils.getConfig("kuaishou_third_appid"));
-            param.put("secret", PropertiesUtils.getConfig("kuaishou_third_secret"));
-        }
-
+        param.put("app_id", appId);
+        param.put("secret", secret);
         param.put("refresh_token", refreshToken);
         try {
             CtopOauthToken oauthToken = ctopOauthTokenMapper.selectByAccountId(accountId);
@@ -142,7 +136,7 @@ public class CtopOauthTokenServiceImpl extends ServiceImpl<CtopOauthTokenMapper,
                 log.error("查询token信息返回结果为空,accountId:{}", accountId);
                 return;
             }
-            XxlJobHelper.log("刷新token,入參:{},token:{}", param,headers);
+            XxlJobHelper.log("刷新token,入參:{},token:{}", param, headers);
             String result = HttpUtils.httpPostRequest(url, param, headers);
             JSONObject resultJson = JSONObject.parseObject(result);
             log.info("快手刷新token返回结果:{}", refreshToken);

+ 9 - 7
module-common/src/main/java/cn/com/ctop/common/module/service/impl/MaterialCutFrameServiceImpl.java

@@ -1,26 +1,23 @@
 package cn.com.ctop.common.module.service.impl;
 
-import cn.com.ctop.common.module.constant.OssConstant;
 import cn.com.ctop.common.module.entity.MaterialCutFrame;
 import cn.com.ctop.common.module.entity.MaterialCutFrameTask;
 import cn.com.ctop.common.module.mapper.MaterialCutFrameMapper;
 import cn.com.ctop.common.module.service.IMaterialCutFrameService;
 import cn.com.ctop.common.module.service.IMaterialCutFrameTaskService;
-import cn.com.ctop.common.module.utils.*;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.CloudVideoProcessUtil;
+import cn.com.ctop.common.module.utils.LoadFileUtil;
+import cn.com.ctop.common.module.utils.MpsUtils;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyuncs.DefaultAcsClient;
 import com.aliyuncs.IAcsClient;
-import com.aliyuncs.mts.model.v20140618.QuerySnapshotJobListRequest;
-import com.aliyuncs.mts.model.v20140618.QuerySnapshotJobListResponse;
 import com.aliyuncs.mts.model.v20140618.SubmitSnapshotJobRequest;
 import com.aliyuncs.mts.model.v20140618.SubmitSnapshotJobResponse;
 import com.aliyuncs.profile.DefaultProfile;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -272,5 +269,10 @@ public class MaterialCutFrameServiceImpl extends ServiceImpl<MaterialCutFrameMap
 
     }
 
+    @Override
+    public JSONObject getCutFrameByVideoMd5(String photoId, String imageToken) {
+        return materialCutFrameMapper.getCutFrameByVideoMd5(photoId, imageToken);
+    }
+
 
 }

+ 52 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/impl/OauthConfigServiceImpl.java

@@ -0,0 +1,52 @@
+package cn.com.ctop.common.module.service.impl;
+
+import cn.com.ctop.common.module.entity.OauthConfig;
+import cn.com.ctop.common.module.mapper.OauthConfigMapper;
+import cn.com.ctop.common.module.service.IOauthConfigService;
+import cn.com.ctop.common.module.utils.Check;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 授权配置信息
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-01-26
+ */
+@Service
+public class OauthConfigServiceImpl extends ServiceImpl<OauthConfigMapper, OauthConfig> implements IOauthConfigService {
+    @Autowired
+    private OauthConfigMapper configMapper;
+
+    @Override
+    public OauthConfig getConfigByAppId(Long appId) {
+        QueryWrapper<OauthConfig> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("app_id", appId);
+        OauthConfig config = this.getOne(queryWrapper);
+        return config;
+    }
+
+    @Override
+    public Map<Long, String> getConfigMapByMediaId(int mediaId) {
+
+        Map<Long, String> map = new HashMap<>();
+        List<JSONObject> list = configMapper.getListByMediaId(mediaId);
+        if (!Check.isNull(list)) {
+            for (int i = 0; i < list.size(); i++) {
+                JSONObject jsonObject = list.get(i);
+                map.put(jsonObject.getLong("app_id"), jsonObject.getString("secret"));
+            }
+
+        }
+
+        return map;
+    }
+}

+ 9 - 1
module-common/src/main/java/cn/com/ctop/common/module/service/impl/RefreshTokenServiceImpl.java

@@ -5,6 +5,7 @@ import cn.com.ctop.common.module.entity.OauthAgentToken;
 import cn.com.ctop.common.module.mapper.CtopOauthTokenMapper;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
 import cn.com.ctop.common.module.service.IOauthAgentTokenService;
+import cn.com.ctop.common.module.service.IOauthConfigService;
 import cn.com.ctop.common.module.service.IRefreshTokenService;
 import cn.com.ctop.common.module.utils.Check;
 import cn.com.ctop.common.module.utils.CtopAdConstant;
@@ -15,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.Map;
 
 @Slf4j
 @Service
@@ -25,6 +27,8 @@ public class RefreshTokenServiceImpl implements IRefreshTokenService {
     private ICtopOauthTokenService oauthTokenService;
     @Autowired
     private IOauthAgentTokenService agentTokenService;
+    @Autowired
+    private IOauthConfigService configService;
 
     /**
      * 获取所有token
@@ -33,13 +37,17 @@ public class RefreshTokenServiceImpl implements IRefreshTokenService {
      */
     @Override
     public void getKuaiShouRefresh() {
+
+
         List<CtopOauthToken> oauthTokens = oauthTokenMapper.selectKuaiShouTokens(CtopAdConstant.PLATFORM_TYPE_KUAISHOU);
         if (!Check.isNull(oauthTokens)) {
+            Map<Long, String> configMap = configService.getConfigMapByMediaId(CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT);
             for (CtopOauthToken oauthToken : oauthTokens) {
                 XxlJobHelper.log("刷新token,accountId:{}", oauthToken.getAccountId());
                 //快手
                 if (CtopAdConstant.PLATFORM_TYPE_KUAISHOU.equals(oauthToken.getMediaId().trim())) {
-                    oauthTokenService.getKuaiShouRefreshToken(oauthToken.getAccountId(), oauthToken.getAccessToken(), oauthToken.getRefreshToken(), oauthToken.getAgentType());
+                    String secret = configMap.get(oauthToken.getAppId());
+                    oauthTokenService.getKuaiShouRefreshToken(oauthToken.getAccountId(), oauthToken.getAccessToken(), oauthToken.getRefreshToken(), oauthToken.getAppId(), secret);
                 }
             }
         } else {

+ 16 - 0
module-common/src/main/java/cn/com/ctop/common/module/utils/KuaishouInterfaceConstant.java

@@ -322,5 +322,21 @@ public class KuaishouInterfaceConstant {
      * 频库-视频关联创意数查询
      */
     public static final String VIDEO_RELATE_CREATIVES = "/rest/openapi/v1/file/ad/video/relate/creatives";
+/**
+     * 查询加速探索信息接口
+     */
+    public static final String UNIT_EXPLORE_INFO_GET = "/rest/openapi/v1/ad_unit/explore/info/get";
+/**
+     * 广告组的加速探索预算设置
+     */
+    public static final String UNIT_EXPLORE_BUDGET_UPDATE = "/rest/openapi/v1/ad_unit/explore/budget/update";
+/**
+     * 暂停广告组的加速探索预算
+     */
+    public static final String UNIT_EXPLORE_STATUS_PAUSE = "/rest/openapi/v1/ad_unit/explore/status/pause";
+/**
+     * 查询广告组的加速探索报表接口
+     */
+    public static final String QUERY_SPEED_EXPLORE_REPORT = "/rest/openapi/v1/report/speed_explore";
 
 }

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

@@ -0,0 +1,50 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.toutiao.modules.report.service.IBytedanceVideoReportService;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.jeecg.common.util.DateUtils;
+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;
+
+@Component
+public class BaseReportVideoDailyLoadJob {
+
+    @Autowired
+    ICtopOauthTokenService oauthTokenService;
+    @Autowired
+    IBytedanceVideoReportService bytedanceVideoReportService;
+    private ExecutorService executorService = Executors.newFixedThreadPool(10);
+    private CountDownLatch countDownLatch;
+    @XxlJob("baseReportVideoDailyLoadJob")
+    public void execute() throws Exception {
+        List<CtopOauthToken> tokens = oauthTokenService.selectToutiaoToken();
+        countDownLatch = new CountDownLatch(tokens.size());
+        String statDate= DateUtils.formatDate(DateUtils.addDay(new Date(), -1));
+        tokens.forEach(token -> executorService.submit(() -> {
+            try {
+                bytedanceVideoReportService.pullVideoReport(token,statDate,statDate,1);
+            } catch (Exception e) {
+                XxlJobHelper.log("头条视频报表基础数据拉取异常:{}",e.getMessage());
+            } finally {
+                countDownLatch.countDown();
+            }
+        }));
+        try {
+            countDownLatch.await();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        if(!executorService.isShutdown()){
+            executorService.shutdown();
+        }
+    }
+}

+ 1 - 1
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMaterialsLoadJob.java

@@ -17,7 +17,7 @@ import java.util.concurrent.Executors;
 public class BytedanceMaterialsLoadJob {
     @Autowired
     private ICtopOauthTokenService tokenService;
-    static ExecutorService executorService = Executors.newFixedThreadPool(4);
+    static ExecutorService executorService = Executors.newFixedThreadPool(10);
     //线程计数器
     static CountDownLatch countDownLatch = null;
     @Autowired

+ 30 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ETLReportVideoCleanJob.java

@@ -0,0 +1,30 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.toutiao.modules.link.service.IETLReportBytedanceVideoService;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.jeecg.common.util.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+@Component
+public class ETLReportVideoCleanJob {
+
+    @Autowired
+    IETLReportBytedanceVideoService etlReportBytedanceVideoService;
+
+    @XxlJob("ETLReportVideoCleanJob")
+    public void execute() throws Exception {
+        String statDate = DateUtils.formatDate(DateUtils.addDay(new Date(), -1));
+        try {
+            etlReportBytedanceVideoService.cleanETL(statDate);
+        } catch (Exception e) {
+            XxlJobHelper.log("头条视频报表基础数据拉取异常:{}", e.getMessage());
+        } finally {
+            XxlJobHelper.log("ETLReportVideoCleanJob is finish");
+        }
+    }
+}
+

+ 22 - 1
module-job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/KuaiShouAlarmRuleJob.java

@@ -1,16 +1,27 @@
 package cn.com.ctop.job.kuaishou.handler;
 
 
+import cn.com.ctop.alarm.modules.entity.RuleAccountTemplate;
+import cn.com.ctop.alarm.modules.mapper.RuleAccountTemplateMapper;
 import cn.com.ctop.alarm.modules.service.IRuleGroupService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.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.HashMap;
+import java.util.List;
+import java.util.Map;
+
 @Component
 public class KuaiShouAlarmRuleJob {
     @Autowired
     private IRuleGroupService ruleGroupService;
 
+    @Autowired
+    private RuleAccountTemplateMapper ruleAccountTemplateMapper;
+    String URLPREFIX = "http://jiaoyangapi.shyouteng.com.cn/jeecg-boot/ruleGroup/checkRulesByAccountId?accountId=";
     /**
      * 定时任务
      *
@@ -21,6 +32,16 @@ public class KuaiShouAlarmRuleJob {
      */
     @XxlJob("kuaiShoualarmRuleJob")
     public void execute() throws Exception {
-        ruleGroupService.checkRules();
+        //查询账户绑定过的规则模板
+        Map<String, Object> map = new HashMap<>();
+        //0状态为启动
+        map.put("template_status", 0);
+        List<RuleAccountTemplate> ruleAccountTemplates = ruleAccountTemplateMapper.selectByMap(map);
+        if (!Check.isNull(ruleAccountTemplates)) {
+            ruleAccountTemplates.forEach(template -> {
+                String url = URLPREFIX + template.getAccountId();
+                HttpUtils.httpGet(url, null, null);
+            });
+        }
     }
 }

+ 4 - 0
module-job-kuaishou/src/main/resources/application-jiaoyang.yml

@@ -228,3 +228,7 @@ xxl:
       logretentiondays: 30
     admin:
       addresses: http://129.28.150.229:8090/xxl-job-admin
+ai:
+  callback:
+    callback-unit-url: http://192.168.1.193:31012/ai_callback_add_group
+    callback-creative-url: http://192.168.1.193:31012/ai_callback_add_creative

+ 278 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/controller/AiKuaiShouAppInfoController.java

@@ -0,0 +1,278 @@
+package cn.com.ctop.kuaishou.modules.ai.controller;
+
+import cn.com.ctop.common.module.annotation.AutoLog;
+import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaiShouAppInfo;
+import cn.com.ctop.kuaishou.modules.ai.service.IAiKuaiShouAppInfoService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ai批量上传应用
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-02-02
+ */
+@Slf4j
+@Api(tags = "ai批量上传应用")
+@RestController
+@RequestMapping("/ai/aiKuaiShouAppInfo")
+public class AiKuaiShouAppInfoController {
+    @Autowired
+    private IAiKuaiShouAppInfoService aiKuaiShouAppInfoService;
+
+
+    @PostMapping(value = "/importAppExcel")
+    public Result<?> importExcel(@RequestParam("file") MultipartFile file,
+                                 @RequestParam("accountId") Long accountId,
+                                 @RequestParam("imageToken") String imageToken) {
+
+
+        FileInputStream fis = null;
+        try {
+
+            JSONObject json = aiKuaiShouAppInfoService.importExcel(file, accountId, imageToken);
+            //          System.out.println("导入是否成功:" + flag);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return Result.ok("文件导入成功!");
+    }
+
+
+    /**
+     * 分页列表查询
+     *
+     * @param aiKuaiShouAppInfo
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "ai批量上传应用-分页列表查询")
+    @ApiOperation(value = "ai批量上传应用-分页列表查询", notes = "ai批量上传应用-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<AiKuaiShouAppInfo>> queryPageList(AiKuaiShouAppInfo aiKuaiShouAppInfo,
+                                                          @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                          HttpServletRequest req) {
+        Result<IPage<AiKuaiShouAppInfo>> result = new Result<>();
+        QueryWrapper<AiKuaiShouAppInfo> queryWrapper = QueryGenerator.initQueryWrapper(aiKuaiShouAppInfo, req.getParameterMap());
+        Page<AiKuaiShouAppInfo> page = new Page<AiKuaiShouAppInfo>(pageNo, pageSize);
+        IPage<AiKuaiShouAppInfo> pageList = aiKuaiShouAppInfoService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 添加
+     *
+     * @param aiKuaiShouAppInfo
+     * @return
+     */
+    @AutoLog(value = "ai批量上传应用-添加")
+    @ApiOperation(value = "ai批量上传应用-添加", notes = "ai批量上传应用-添加")
+    @PostMapping(value = "/add")
+    public Result<AiKuaiShouAppInfo> add(@RequestBody AiKuaiShouAppInfo aiKuaiShouAppInfo) {
+        Result<AiKuaiShouAppInfo> result = new Result<>();
+        try {
+            aiKuaiShouAppInfoService.save(aiKuaiShouAppInfo);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param aiKuaiShouAppInfo
+     * @return
+     */
+    @AutoLog(value = "ai批量上传应用-编辑")
+    @ApiOperation(value = "ai批量上传应用-编辑", notes = "ai批量上传应用-编辑")
+    @PutMapping(value = "/edit")
+    public Result<AiKuaiShouAppInfo> edit(@RequestBody AiKuaiShouAppInfo aiKuaiShouAppInfo) {
+        Result<AiKuaiShouAppInfo> result = new Result<AiKuaiShouAppInfo>();
+        AiKuaiShouAppInfo aiKuaiShouAppInfoEntity = aiKuaiShouAppInfoService.getById(aiKuaiShouAppInfo.getId());
+        if (aiKuaiShouAppInfoEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = aiKuaiShouAppInfoService.updateById(aiKuaiShouAppInfo);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "ai批量上传应用-通过id删除")
+    @ApiOperation(value = "ai批量上传应用-通过id删除", notes = "ai批量上传应用-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            aiKuaiShouAppInfoService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "ai批量上传应用-批量删除")
+    @ApiOperation(value = "ai批量上传应用-批量删除", notes = "ai批量上传应用-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<AiKuaiShouAppInfo> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<AiKuaiShouAppInfo> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.aiKuaiShouAppInfoService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "ai批量上传应用-通过id查询")
+    @ApiOperation(value = "ai批量上传应用-通过id查询", notes = "ai批量上传应用-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<AiKuaiShouAppInfo> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<AiKuaiShouAppInfo> result = new Result<>();
+        AiKuaiShouAppInfo aiKuaiShouAppInfo = aiKuaiShouAppInfoService.getById(id);
+        if (aiKuaiShouAppInfo == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(aiKuaiShouAppInfo);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<AiKuaiShouAppInfo> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                AiKuaiShouAppInfo aiKuaiShouAppInfo = JSON.parseObject(deString, AiKuaiShouAppInfo.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(aiKuaiShouAppInfo, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<AiKuaiShouAppInfo> pageList = aiKuaiShouAppInfoService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "ai批量上传应用列表");
+        mv.addObject(NormalExcelConstants.CLASS, AiKuaiShouAppInfo.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("ai批量上传应用列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<AiKuaiShouAppInfo> listAiKuaiShouAppInfos = ExcelImportUtil.importExcel(file.getInputStream(), AiKuaiShouAppInfo.class, params);
+                aiKuaiShouAppInfoService.saveBatch(listAiKuaiShouAppInfos);
+                return Result.ok("文件导入成功!数据行数:" + listAiKuaiShouAppInfos.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 142 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/controller/KuaiShouCreativeRefusalController.java

@@ -0,0 +1,142 @@
+package cn.com.ctop.kuaishou.modules.ai.controller;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.service.IMaterialCutFrameService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCreative;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCreativeService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouMaterialUploadService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Slf4j
+@Api(tags = "快手-创意拒审重提")
+@RestController
+@RequestMapping("/kuaishou/creative/")
+public class KuaiShouCreativeRefusalController {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IKuaiShouCreativeService creativeService;
+    @Autowired
+    private IKuaiShouUpdateService updateService;
+    @Autowired
+    private IMaterialCutFrameService cutFrameService;
+    @Autowired
+    private IKuaiShouImageGetService imageGetService;
+    @Autowired
+    private IKuaiShouMaterialUploadService uploadService;
+    static ExecutorService executorService = Executors.newFixedThreadPool(80);
+
+    /**
+     * 吃创意拒审重提
+     *
+     * @param requestJson
+     * @return
+     */
+    @PostMapping(value = "again")
+    public JSONObject again(@RequestBody JSONObject requestJson) {
+        JSONObject returnJson = new JSONObject();
+        try {
+            if (Check.isNull(requestJson)) {
+                throw new Exception("入参不能为空");
+            }
+            Long accountId = requestJson.getLong("accountId");
+            if (Check.isNull(accountId)) {
+                throw new Exception("请输入账户id");
+            }
+            CtopOauthToken oauthToken = tokenService.getTokenByAccountId(accountId);
+            if (Check.isNull(oauthToken)) {
+                throw new Exception("未获取到账户信息");
+            }
+            Integer updateType = requestJson.getInteger("updateType"); //  0 更换封面 1 修改广告语
+            if (Check.isNull(updateType)) {
+                throw new Exception("请输入修改类型");
+            }
+            JSONArray creativeIds = requestJson.getJSONArray("creativeIds");
+            if (Check.isNull(creativeIds)) {
+                creativeIds = creativeService.getCreativeIds(accountId);
+            }
+            for (int i = 0; i < creativeIds.size(); i++) {
+                Long creativeId = creativeIds.getLong(i);
+                executorService.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        KuaiShouCreative creative = creativeService.getCreativeByCreativeId(creativeId);
+                        if (!Check.isNull(creative)) {
+                            JSONObject updateJson = new JSONObject();
+                            updateJson.put("creativeId", creativeId);
+                            if (updateType == 0) {  //  更换封面
+                                JSONObject cutJson = cutFrameService.getCutFrameByVideoMd5(creative.getPhotoId(), creative.getImageToken());
+                                if (!Check.isNull(cutJson)) {
+                                    String signature = cutJson.getString("signature");
+                                    String url = cutJson.getString("url");
+                                    String imageToken = getImageToken(signature, accountId, oauthToken.getAccessToken(), url);
+                                    if (!Check.isNull(imageToken)) {
+                                        updateJson.put("imageToken", imageToken);
+                                    }
+                                }
+                            } else if (updateType == 1) { // 修改广告语
+                                String updateDescription = creativeService.convertMoString(creative.getDescription());
+                                updateJson.put("description", updateDescription);
+                            }
+                            Map<String, Object> creativeMap = updateService.updateCreative(oauthToken.getAccessToken(), accountId, updateJson);
+                            Integer code = (Integer) creativeMap.get("code");
+                            if (code == 0) {
+                                log.info("自动投放拒审重提成功,accountId:{},creativeId:{}", accountId, creativeId);
+                            } else {
+                                log.info("自动投放拒审重提失败,accountId:{},creativeId:{}", accountId, creativeId);
+                            }
+                            try {
+                                Thread.sleep(1000L);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                });
+            }
+            returnJson.put("code", 0);
+            returnJson.put("message", "异步提交中");
+        } catch (Exception e) {
+            e.printStackTrace();
+            returnJson.put("code", 0);
+            returnJson.put("message", e.getMessage());
+        }
+        return returnJson;
+    }
+
+
+    private String getImageToken(String md5, Long accountId, String accessToken, String url) {
+        String imageToken = null;
+        QueryWrapper<KuaiShouImageGet> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id", accountId);
+        queryWrapper.eq("signature", md5);
+        queryWrapper.last("limit 1");
+        KuaiShouImageGet imageGet = imageGetService.getOne(queryWrapper);
+        if (!Check.isNull(imageGet)) {
+            imageToken = imageGet.getImageToken();
+        } else {
+            imageToken = uploadService.kuauiShouImageUpload(url, md5, accountId, accessToken);
+        }
+        return imageToken;
+
+    }
+
+}

+ 120 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/entity/AiKuaiShouAppInfo.java

@@ -0,0 +1,120 @@
+package cn.com.ctop.kuaishou.modules.ai.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.util.Date;
+
+/**
+ * ai批量上传应用
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-02-02
+ */
+@Data
+@TableName("ctop_ai_kuaishou_app_info")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_ai_kuaishou_app_info对象", description = "ai批量上传应用")
+public class AiKuaiShouAppInfo {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 账户id
+     */
+    @Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
+    private Long accountId;
+    /**
+     * 应用标记
+     */
+    @Excel(name = "应用标记", width = 15)
+    @ApiModelProperty(value = "应用标记")
+    private String appVersion;
+    /**
+     * 应用名称
+     */
+    @Excel(name = "应用名称", width = 15)
+    @ApiModelProperty(value = "应用名称")
+    private String appName;
+    /**
+     * 应用包名
+     */
+    @Excel(name = "应用包名	", width = 15)
+    @ApiModelProperty(value = "应用包名	")
+    private String packageName;
+    /**
+     * 应用类型 1:Android应用下载,2:Android网页游戏,3:iOS应用下载,4:iOS网页游戏
+     */
+    @Excel(name = "应用类型 1:Android应用下载,2:Android网页游戏,3:iOS应用下载,4:iOS网页游戏", width = 15)
+    @ApiModelProperty(value = "应用类型 1:Android应用下载,2:Android网页游戏,3:iOS应用下载,4:iOS网页游戏")
+    private Integer platform;
+    /**
+     * 应用下载地址/网页游戏链接地址
+     */
+    @Excel(name = "应用下载地址/网页游戏链接地址	", width = 15)
+    @ApiModelProperty(value = "应用下载地址/网页游戏链接地址	")
+    private String url;
+    /**
+     * 是否接入快手广告监测SDK	 0:未接入,1:已接入
+     */
+    @Excel(name = "是否接入快手广告监测SDK	 0:未接入,1:已接入", width = 15)
+    @ApiModelProperty(value = "是否接入快手广告监测SDK	 0:未接入,1:已接入")
+    private Integer useSdk;
+    /**
+     * app隐私政策链接 安卓类应用必填
+     */
+    @Excel(name = "app隐私政策链接 安卓类应用必填", width = 15)
+    @ApiModelProperty(value = "app隐私政策链接 安卓类应用必填")
+    private String appPrivacyUrl;
+    private String trackUrl;
+    /**
+     * app文件MD5
+     */
+    @Excel(name = "app文件MD5", width = 15)
+    @ApiModelProperty(value = "app文件MD5")
+    private String appMd5;
+    /**
+     * 状态
+     */
+    @Excel(name = "状态", width = 15)
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+    /**
+     * app_id
+     */
+    @Excel(name = "app_id", width = 15)
+    @ApiModelProperty(value = "app_id")
+    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 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;
+}

+ 52 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/entity/KuaishouAccountCreativeOverrunInfo.java

@@ -0,0 +1,52 @@
+package cn.com.ctop.kuaishou.modules.ai.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 快手账户创意创建超限记录信息
+ * @author jeecg-boot
+ * @date   2021-01-30
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_kuaishou_account_creative_overrun_info")
+@EqualsAndHashCode(callSuper = false)
+public class KuaishouAccountCreativeOverrunInfo {
+
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	/**accountId*/
+	private Long accountId;
+	/**stateDate*/
+	private String stateDate;
+	/**
+	 * 超限时间
+	 */
+	private String overrunTime;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+
+	public KuaishouAccountCreativeOverrunInfo(Long advertiserId, String date,String dateTime) {
+		this.accountId = advertiserId;
+		this.stateDate = date;
+		this.overrunTime = dateTime;
+		this.createTime = new Date();
+		this.updateTime =new Date();
+	}
+}

+ 15 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/AiKuaiShouAppInfoMapper.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.kuaishou.modules.ai.mapper;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaiShouAppInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * ai批量上传应用
+ *
+ * @author: jeecg-boot
+ * @date: 2021-02-02
+ * @cersion: V1.0
+ */
+public interface AiKuaiShouAppInfoMapper extends BaseMapper<AiKuaiShouAppInfo> {
+
+}

+ 14 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/KuaishouAccountCreativeOverrunInfoMapper.java

@@ -0,0 +1,14 @@
+package cn.com.ctop.kuaishou.modules.ai.mapper;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouAccountCreativeOverrunInfo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 快手账户创意创建超限记录信息
+ * @author: jeecg-boot
+ * @date:   2021-01-30
+ * @cersion: V1.0
+ */
+public interface KuaishouAccountCreativeOverrunInfoMapper extends BaseMapper<KuaishouAccountCreativeOverrunInfo> {
+
+}

+ 5 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/xml/AiKuaiShouAppInfoMapper.xml

@@ -0,0 +1,5 @@
+<?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.kuaishou.modules.ai.mapper.AiKuaiShouAppInfoMapper">
+
+</mapper>

+ 5 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/mapper/xml/KuaishouAccountCreativeOverrunInfoMapper.xml

@@ -0,0 +1,5 @@
+<?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.kuaishou.modules.ai.mapper.KuaishouAccountCreativeOverrunInfoMapper">
+
+</mapper>

+ 17 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/IAiKuaiShouAppInfoService.java

@@ -0,0 +1,17 @@
+package cn.com.ctop.kuaishou.modules.ai.service;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaiShouAppInfo;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @Description: ai批量上传应用
+ * @Author: jeecg-boot
+ * @Date: 2021-02-02
+ * @Version: V1.0
+ */
+public interface IAiKuaiShouAppInfoService extends IService<AiKuaiShouAppInfo> {
+
+    JSONObject importExcel(MultipartFile file, Long accountId, String imageToken);
+}

+ 20 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/IKuaishouAccountCreativeOverrunInfoService.java

@@ -0,0 +1,20 @@
+package cn.com.ctop.kuaishou.modules.ai.service;
+
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouAccountCreativeOverrunInfo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: 快手账户创意创建超限记录信息
+ * @Author: jeecg-boot
+ * @Date:   2021-01-30
+ * @Version: V1.0
+ */
+public interface IKuaishouAccountCreativeOverrunInfoService extends IService<KuaishouAccountCreativeOverrunInfo> {
+
+    void stopCreativeBySignature(Long accountId,String signature);
+
+
+    void updateOverrunInfo(Long advertiserId);
+
+    KuaishouAccountCreativeOverrunInfo getByParams(Long accountId, String date);
+}

+ 151 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/AiKuaiShouAppInfoServiceImpl.java

@@ -0,0 +1,151 @@
+package cn.com.ctop.kuaishou.modules.ai.service.impl;
+
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaiShouAppInfo;
+import cn.com.ctop.kuaishou.modules.ai.mapper.AiKuaiShouAppInfoMapper;
+import cn.com.ctop.kuaishou.modules.ai.service.IAiKuaiShouAppInfoService;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * ai批量上传应用
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-02-02
+ */
+@Service
+public class AiKuaiShouAppInfoServiceImpl extends ServiceImpl<AiKuaiShouAppInfoMapper, AiKuaiShouAppInfo> implements IAiKuaiShouAppInfoService {
+
+    /**
+     * 文件导入
+     *
+     * @param
+     * @param accountId
+     * @param imageToken
+     * @return
+     */
+    @Override
+    public JSONObject importExcel(MultipartFile myFile, Long accountId, String imageToken) {
+        try {
+            Workbook workbook = null;
+            String fileName = myFile.getOriginalFilename();
+            if (fileName.endsWith("XLS")) {
+                //2003
+                workbook = new HSSFWorkbook(myFile.getInputStream());
+            } else if (fileName.endsWith("XLSX")) {
+                //2007
+                workbook = new XSSFWorkbook(myFile.getInputStream());
+            } else {
+                //   throw new Exception("文件不是Excel文件");
+            }
+
+            Sheet sheet = workbook.getSheet("Sheet1");
+            int rows = sheet.getLastRowNum();// 指的行数,一共有多少行+
+            if (rows == 0) {
+                // throw new Exception("请填写数据");
+            }
+            for (int i = 1; i <= rows + 1; i++) {
+                // 读取左上端单元格
+                Row row = sheet.getRow(i);
+                // 行不为空
+                if (row != null) {
+                    // **读取cell**
+                    AiKuaiShouAppInfo appInfo = new AiKuaiShouAppInfo();
+
+                    String appName = getCellValue(row.getCell(0));
+                    appInfo.setAppName(appName);
+
+                    String packageName = getCellValue(row.getCell(1));
+                    appInfo.setPackageName(packageName);
+
+                    String appVersion = getCellValue(row.getCell(2));
+                    appInfo.setAppVersion(appVersion);
+
+                    String useSdk = getCellValue(row.getCell(3));
+                    if (!Check.isNull(useSdk)) {
+                        appInfo.setUseSdk(Integer.valueOf(useSdk));
+                    }
+                    String appPrivacyUrl = getCellValue(row.getCell(4));
+                    if (!Check.isNull(appPrivacyUrl)) {
+                        appInfo.setAppPrivacyUrl(appPrivacyUrl);
+                    }
+
+                    String trackUrl = getCellValue(row.getCell(5));
+                    if (!Check.isNull(trackUrl)) {
+                        appInfo.setTrackUrl(trackUrl);
+                    }
+                    //考试时间
+                  /*  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//小写的mm表示的是分钟
+                    String dateString = getCellValue(row.getCell(3));
+                    if (!StringUtils.isEmpty(dateString)) {
+                        Date date = sdf.parse(dateString);
+                        student.setTime(date);
+                    }
+                    studentMapper.insert(student);*/
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+
+        }
+        return null;
+    }
+
+
+    private String getCellValue(Cell cell) {
+        String value = "";
+        if (cell != null) {
+            // 以下是判断数据的类型
+            switch (cell.getCellType()) {
+                case HSSFCell.CELL_TYPE_NUMERIC: // 数字
+                    value = cell.getNumericCellValue() + "";
+                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
+                        Date date = cell.getDateCellValue();
+                        if (date != null) {
+                            value = new SimpleDateFormat("yyyy-MM-dd").format(date);
+                        } else {
+                            value = "";
+                        }
+                    } else {
+                        value = new DecimalFormat("0").format(cell.getNumericCellValue());
+                    }
+                    break;
+                case HSSFCell.CELL_TYPE_STRING: // 字符串
+                    value = cell.getStringCellValue();
+                    break;
+                case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
+                    value = cell.getBooleanCellValue() + "";
+                    break;
+                case HSSFCell.CELL_TYPE_FORMULA: // 公式
+                    value = cell.getCellFormula() + "";
+                    break;
+                case HSSFCell.CELL_TYPE_BLANK: // 空值
+                    value = "";
+                    break;
+                case HSSFCell.CELL_TYPE_ERROR: // 故障
+                    value = "非法字符";
+                    break;
+                default:
+                    value = "未知类型";
+                    break;
+            }
+        }
+        return value.trim();
+    }
+}

+ 20 - 5
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/AiKuaishouNewCreateCampaignServiceImpl.java

@@ -8,8 +8,10 @@ import cn.com.ctop.common.module.service.IMaterialCutFrameService;
 import cn.com.ctop.common.module.service.IMaterialImageInfoService;
 import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaishouAccountTargetTemplate;
 import cn.com.ctop.kuaishou.modules.ai.entity.AiKuaishouStrategyMapCreative;
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouAccountCreativeOverrunInfo;
 import cn.com.ctop.kuaishou.modules.ai.service.IAiKuaishouNewCreateCampaign;
 import cn.com.ctop.kuaishou.modules.ai.service.IAiKuaishouStrategyMapCreativeService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouAccountCreativeOverrunInfoService;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouVideoRelateCreatives;
@@ -23,6 +25,7 @@ import org.jeecg.common.util.JsonResourceUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -47,9 +50,12 @@ public class AiKuaishouNewCreateCampaignServiceImpl implements IAiKuaishouNewCre
     private IKuaiShouImageGetService imageGetService;
     @Autowired
     private IKuaiShouMaterialUploadService materialUploadService;
-    @Autowired
+    @Resource
     private KuaiShouVideoGetMapper videoGetMapper;
-
+    @Autowired
+    private IKuaishouVideoRelateCreativesService relateCreativesService;
+    @Autowired
+    private IKuaishouAccountCreativeOverrunInfoService overrunInfoService;
 
     @Override
     public void kuaishouAiAdsNewMaterialCreativity(AiKuaishouAccountTargetTemplate targetTemplate) {
@@ -119,6 +125,10 @@ public class AiKuaishouNewCreateCampaignServiceImpl implements IAiKuaishouNewCre
         String unitNamePrefix = targetTemplate.getTitlePrefix() + "素材上新"+ targetTemplate.getTitleMiddle()+ timestamp;
         int unitCnt = 0;
         for(KuaiShouVideoGet videoItem: newVideos){
+            KuaishouAccountCreativeOverrunInfo overrunInfo = overrunInfoService.getByParams(accountId,DateUtils.formatDate(new Date()));
+            if(null!=overrunInfo){
+                return;
+            }
             unitCnt ++;
             String unitName = unitNamePrefix + "-" + unitCnt;
             JSONObject unitParams = createUnitParams(token, newCampaignId, targetTemplate, unitName);
@@ -198,6 +208,10 @@ public class AiKuaishouNewCreateCampaignServiceImpl implements IAiKuaishouNewCre
         String unitNamePrefix = targetTemplate.getTitlePrefix() + "爆量素材"+ targetTemplate.getTitleMiddle()+timestamp;
         int unitCnt = 0;
         for(KuaiShouVideoGet videoItem: highQualityVideos){
+            KuaishouAccountCreativeOverrunInfo overrunInfo  =  overrunInfoService.getByParams(accountId,DateUtils.formatDate(new Date()));
+            if(null!=overrunInfo){
+                return;
+            }
             unitCnt ++;
             String unitName = unitNamePrefix + "-" + unitCnt;
             JSONObject unitParams = createUnitParams(token, newCampaignId, targetTemplate, unitName);
@@ -222,9 +236,6 @@ public class AiKuaishouNewCreateCampaignServiceImpl implements IAiKuaishouNewCre
         }
 
     }
-
-    @Autowired
-    private IKuaishouVideoRelateCreativesService relateCreativesService;
     @Override
     public void kuaishouAiAddNewMaterialCreativity(AiKuaishouAccountTargetTemplate targetTemplate,Integer matNum) {
         Long accountId = targetTemplate.getAccountId();
@@ -281,6 +292,10 @@ public class AiKuaishouNewCreateCampaignServiceImpl implements IAiKuaishouNewCre
         String unitNamePrefix = targetTemplate.getTitlePrefix() + "素材上新"+ targetTemplate.getTitleMiddle()+ timestamp;
         int unitCnt = 0;
         for(KuaishouVideoRelateCreatives videoItem: kuaishouVideoRelateCreatives){
+            KuaishouAccountCreativeOverrunInfo overrunInfo  =  overrunInfoService.getByParams(accountId,DateUtils.formatDate(new Date()));
+            if(null!=overrunInfo){
+                return;
+            }
             unitCnt ++;
             KuaiShouVideoGet videoGet = videoGetService.getVideoByPhotoId(videoItem.getPhotoId());
             if(null == videoGet){

+ 22 - 8
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/KuaiShouCreateServiceImpl.java

@@ -165,6 +165,16 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                 if (!Check.isNull(groupCreateJson.getLong("fiction_id"))) {
                     createJson.put("fiction_id", groupCreateJson.getLong("fiction_id")); //小说ID
                 }
+
+                if (unit_type == 7) {
+                    if (!Check.isNull(groupCreateJson.getBoolean("smart_cover"))) {
+                        createJson.put("smart_cover", groupCreateJson.getBoolean("smart_cover")); //是否开启智能抽帧
+                    }
+                    if (!Check.isNull(groupCreateJson.getBoolean("asset_mining"))) {
+                        createJson.put("asset_mining", groupCreateJson.getBoolean("asset_mining")); //程序化创意2.0素材挖掘
+                    }
+                }
+
                 if (!Check.isNull(groupCreateJson.getLong("template_id"))) {
                     createJson.put("template_id", groupCreateJson.getLong("template_id")); //定向模板id
                 } else {
@@ -181,7 +191,6 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                     returnJson.put("unit_id", unitId);
                     returnJson.put("code", 0);
                     returnJson.put("message", "广告组创建成功");
-                    returnJson.put("type", 1);
                     KuaiShouGroup group = groupService.selectGroupByUnitId(oauthToken.getAccountId(), unitId);
                     if (!Check.isNull(group)) {
                         returnJson.put("group_create_time", group.getGroupCreateTime());
@@ -200,7 +209,7 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                 } else {
                     returnJson.put("code", -1);
                     returnJson.put("message", unitMap.get("message"));
-                    returnJson.put("type", 1);
+
                 }
                 returnArr.add(returnJson);
             } catch (Exception e) {
@@ -208,7 +217,6 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                 returnJson.put("group_uuid", group_uuid);
                 returnJson.put("code", -1);
                 returnJson.put("message", e.getMessage());
-                returnJson.put("type", 1);
                 returnArr.add(returnJson);
             }
         }
@@ -303,10 +311,11 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                 Map<String, Object> creativeMap = iKuaishouInterfaceService.creativeCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), createJson, 1);
                 JSONObject returnJson = new JSONObject();
                 returnJson.put("creative_uuid", creative_uuid);
+                returnJson.put("unit_id", unit_id);
+                returnJson.put("type", 1);
                 if ((Integer) creativeMap.get("code") == 0) {
                     Long creativeId = (Long) creativeMap.get("creativeId");
                     returnJson.put("creative_id", creativeId);
-                    returnJson.put("unit_id", unit_id);
                     returnJson.put("code", 0);
                     returnJson.put("message", "广告创意创建成功");
                 } else {
@@ -320,6 +329,8 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                 returnJson.put("creative_uuid", creative_uuid);
                 returnJson.put("message", e.getMessage());
                 returnJson.put("code", -1);
+                returnJson.put("unit_id", unit_id);
+                returnJson.put("type", 1);
                 returnArr.add(returnJson);
             }
         }
@@ -364,6 +375,8 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                     }
                 }
                 programJson.put("cover_image_tokens", cover_image_tokens);
+            } else {
+                programJson.put("cover_image_tokens", new JSONArray());
             }
             if (!Check.isNull(programCreativeJson.getLong("site_id"))) {
                 programJson.put("site_id", programCreativeJson.getLong("site_id"));
@@ -398,17 +411,17 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
             String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.PROGRAM_CREATE;
             String result = HttpUtils.kuaiShouhttpPostRequest(url, programJson.toJSONString(), headers);
             JSONObject resultJson = JSONObject.parseObject(result);
+            log.info("创建程序化创意返回结果:{}", resultJson);
             JSONObject returnJson = new JSONObject();
             returnJson.put("creative_uuid", creative_uuid);
+            returnJson.put("unit_id", unit_id);
+            returnJson.put("type", 2);
             if (!Check.isNull(resultJson)) {
                 if (resultJson.getInteger("code") == 0) {
-                    returnJson.put("unit_id", unit_id);
-                    returnJson.put("type", 2);
                     returnJson.put("code", 0);
                     returnJson.put("message", "程序化创意创建成功");
                 } else {
                     returnJson.put("code", -1);
-                    returnJson.put("type", 2);
                     returnJson.put("message", resultJson.getString("message"));
                 }
             }
@@ -418,8 +431,9 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
             JSONObject returnJson = new JSONObject();
             returnJson.put("creative_uuid", creative_uuid);
             returnJson.put("message", e.getMessage());
-            returnJson.put("type", 2);
             returnJson.put("code", -1);
+            returnJson.put("unit_id", unit_id);
+            returnJson.put("type", 2);
             returnArray.add(returnJson);
         }
         callback(creativeUrl, returnArray, "program_create");

+ 90 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/ai/service/impl/KuaishouAccountCreativeOverrunInfoServiceImpl.java

@@ -0,0 +1,90 @@
+package cn.com.ctop.kuaishou.modules.ai.service.impl;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouAccountCreativeOverrunInfo;
+import cn.com.ctop.kuaishou.modules.ai.mapper.KuaishouAccountCreativeOverrunInfoMapper;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaiShouCreateService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouAccountCreativeOverrunInfoService;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCreative;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouVideoGetMapper;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCreativeService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouVideoRelateCreativesService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xxl.job.core.util.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.query.QueryCondition;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 快手账户创意创建超限记录信息
+ * @author jeecg-boot
+ * @date   2021-01-30
+ * @version V1.0
+ */
+@Slf4j
+@Service
+public class KuaishouAccountCreativeOverrunInfoServiceImpl extends ServiceImpl<KuaishouAccountCreativeOverrunInfoMapper, KuaishouAccountCreativeOverrunInfo> implements IKuaishouAccountCreativeOverrunInfoService {
+    @Resource
+    private KuaiShouVideoGetMapper videoGetMapper;
+    @Autowired
+    private IKuaiShouCreativeService kuaiShouCreativeService;
+    @Autowired
+    private IKuaiShouUpdateService kuaiShouUpdateService;
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+
+    @Override
+    public void stopCreativeBySignature(Long accountId, String signature) {
+        List<KuaiShouVideoGet> videoGets =videoGetMapper.getPhotoIdsByParams(accountId,signature);
+        if(null==videoGets||videoGets.isEmpty()){
+            log.info("该账户下不存在此视频>>accountId:{},视频编码:{}",accountId,signature);
+            return;
+        }
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        videoGets.forEach(videoGet -> {
+            String photoId = videoGet.getPhotoId();
+            Integer putStatus = 52;
+            List<KuaiShouCreative> creatives = kuaiShouCreativeService.getByParams(accountId,photoId,putStatus);
+            if(null!=creatives&&!creatives.isEmpty()){
+                creatives.forEach(creative->{
+                    kuaiShouUpdateService.updateCreativeStatus(token.getAccessToken(),token.getAccountId(),creative.getCreativeId(),2,"");
+                });
+            }
+        });
+    }
+
+    @Override
+    public void updateOverrunInfo(Long advertiserId) {
+        String date = DateUtil.formatDate(new Date());
+        String dateTime = DateUtil.formatDateTime(new Date());
+        KuaishouAccountCreativeOverrunInfo overrunInfo = getByParams(advertiserId,date);
+        if(null == overrunInfo){
+            overrunInfo = new KuaishouAccountCreativeOverrunInfo(advertiserId,date,dateTime);
+            this.save(overrunInfo);
+        }
+    }
+
+    @Override
+    public KuaishouAccountCreativeOverrunInfo getByParams(Long accountId,String date){
+        QueryWrapper<KuaishouAccountCreativeOverrunInfo> queryWrapper = new QueryWrapper<>();
+        if(null!=accountId&&accountId!=0){
+            queryWrapper.eq("account_id",accountId);
+        }
+        if(null!=date&&!"".equals(date.trim())){
+            queryWrapper.eq("state_date",date);
+        }
+        queryWrapper.orderByDesc("id");
+        queryWrapper.last("limit 1");
+        return this.getOne(queryWrapper);
+    }
+}

+ 1 - 1
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/KuaiShouInterfaceController.java

@@ -38,6 +38,7 @@ public class KuaiShouInterfaceController {
                 result.setSuccess(false);
                 result.setMessage("时间参数不能为空");
                 return result;
+
             }
 
             if(operationTarget == null){
@@ -45,7 +46,6 @@ public class KuaiShouInterfaceController {
                 result.setMessage("类型不能为空");
                 return result;
             }
-
             if(accountId == null){
                 //1:查询当日数据
                 QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();

+ 34 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/KuaishouTemplateController.java

@@ -143,6 +143,40 @@ public class KuaishouTemplateController {
     }
 
 
+    @PostMapping(value = "/updateTemplate")
+    public Result<JSONObject> updateTemplate(@RequestBody JSONObject requestJson) {
+        Result<JSONObject> result = new Result<>();
+        try {
+
+            Long accountId = requestJson.getLong("accountId");
+            if (Check.isNull(accountId)) {
+                throw new Exception("请选择账户id");
+            }
+            CtopOauthToken oauthToken = oauthTokenService.getTokenByAccountId(accountId);
+            if (Check.isNull(oauthToken)) {
+                throw new Exception("未获取到账户信息");
+            }
+            JSONObject returnJson = kuaishouTemplateService.updateTemplate(accountId, oauthToken.getAccessToken(), requestJson);
+            Integer code = returnJson.getInteger("code");
+            if (code == 0) {
+                result.setSuccess(true);
+                result.setMessage("修改成功");
+            } else {
+                result.setSuccess(false);
+                result.setMessage(returnJson.getString("message"));
+            }
+
+
+            // result.setResult(returnJson);
+        } catch (Exception e) {
+            e.printStackTrace();
+            result.setSuccess(false);
+            result.setMessage(e.getMessage());
+        }
+        return result;
+    }
+
+
     /**
      * 添加
      *

+ 1 - 58
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/MaterialRefuseController.java

@@ -192,7 +192,7 @@ public class MaterialRefuseController {
                 requestJson.put("creativeId", creativeId);
                 if (type == 0) {  // 替换修改广告语
                     String description = creativeJson.getString("description");
-                    requestJson.put("description", convertMoString(description));
+                    requestJson.put("description", creativeService.convertMoString(description));
                 } else if (type == 1) { // 替换广告语
                     String updateDescription = jsonObject.getString("updateDescription");
                     String updateActionBarText = jsonObject.getString("updateActionBarText");
@@ -234,61 +234,4 @@ public class MaterialRefuseController {
     }
 
 
-    public static synchronized String convertMoString(String sMo) {
-
-        if (Check.isNull(sMo)) {
-            return null;
-        }
-        String newString = null;
-        try {
-            if (sMo.contains(",")) {
-                return sMo.replace(',', ',');
-            } else if (sMo.contains("~")) {
-                newString = sMo.replace('~', '~');
-            } else if (sMo.contains("。")) {
-                newString = sMo.replace('。', '.');
-            } else if (sMo.contains(";")) {
-                newString = sMo.replace(';', ';');
-            } else if (sMo.contains("!")) {
-                newString = sMo.replace("!", "!");
-            } else if (sMo.contains("?")) {
-                newString = sMo.replace('?', '?');
-            } else if (sMo.contains(":")) {
-                newString = sMo.replace(':', ':');
-            } else if (sMo.contains("“")) {
-                newString = sMo.replace('“', '"');
-            } else if (sMo.contains("”")) {
-                newString = sMo.replace('”', '"');
-            } else if (sMo.contains("<")) {
-                newString = sMo.replace('>', '》').replace('<', '《');
-            } else if (sMo.contains(",")) {
-                newString = sMo.replace(',', ',');
-            } else if (sMo.contains(".")) {
-                newString = sMo.replace('.', '。');
-            } else if (sMo.contains(";")) {
-                newString = sMo.replace(';', ';');
-            } else if (sMo.contains("!")) {
-                newString = sMo.replace("!", "!");
-            } else if (sMo.contains("?")) {
-                newString = sMo.replace('?', '?');
-            } else if (sMo.contains(":")) {
-                newString = sMo.replace(':', ':');
-            } else if (sMo.contains(""")) {
-                newString = sMo.replace('"', '“');
-            } else if (sMo.contains(""")) {
-                newString = sMo.replace('"', '”');
-            } else if (sMo.contains("《")) {
-                newString = sMo.replace('》', '>').replace('《', '<');
-            } else if (sMo.contains("~")) {
-                newString = sMo.replace('~', '~');
-            } else {
-                newString = sMo;
-            }
-
-        } catch (Exception ex) {
-            return sMo;
-        }
-        return newString;
-    }
-
 }

+ 0 - 4
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaiShouVideoGet.java

@@ -68,10 +68,6 @@ public class KuaiShouVideoGet {
     @Excel(name = "视频首帧图片链接", width = 15)
     @ApiModelProperty(value = "视频首帧图片链接")
     private String coverUrl;
-    /**
-     * 视频首帧图片链接
-     */
-
     private String signature;
 
     private Date statDate;

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

@@ -31,7 +31,6 @@ public class KuaishouStrategy {
      * id
      */
     @TableId(type = IdType.AUTO)
-    @ApiModelProperty(value = "id")
     private Long id;
     private String createBy;
     private String creativeTag;
@@ -242,4 +241,6 @@ public class KuaishouStrategy {
      */
     @ApiModelProperty(value = "updateTime")
     private Date updateTime;
+
+    private Integer timerTaskStatus;
 }

+ 2 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaiShouCreativeMapper.java

@@ -26,4 +26,6 @@ public interface KuaiShouCreativeMapper extends BaseMapper<KuaiShouCreative> {
     void delAllCreativesByCampaignId(@Param("accountId") Long accountId, @Param("campaignId") Long campaignId);
 
     List<KuaiShouCreative> queryCreativeInfoByCampaignId(@Param("accountId") Long accountId, @Param("campaignId") Long campaignId);
+
+    List<Long> getCreativeIds(@Param("accountId") Long accountId);
 }

+ 1 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaiShouVideoGetMapper.java

@@ -25,4 +25,5 @@ public interface KuaiShouVideoGetMapper extends BaseMapper<KuaiShouVideoGet> {
     List<KuaiShouVideoGet> selectPhotoIdsByAccountId(Long accountId);
     List<JSONObject> getVideoListByMap(Map<String, Object> requestMap);
 
+    List<KuaiShouVideoGet> getPhotoIdsByParams(Long accountId, String signature);
 }

+ 7 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaiShouCreativeMapper.xml

@@ -141,4 +141,11 @@
          AND campaign_id = #{campaignId}
     </select>
 
+    <select id="getCreativeIds" resultType="java.lang.Long">
+     select  creative_id
+     from ctop_kuaishou_creative
+     where  account_id = #{accountId}
+     and  status = 42
+    </select>
+
 </mapper>

+ 1 - 1
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaiShouGroupTemplateMapper.xml

@@ -51,7 +51,7 @@
     <select id="getIdList" resultType="java.lang.Long">
     select id  from ctop_kuaishou_group_template
     where  task_status = 0
-    order by create_time desc
+    order by create_time asc
     limit 70
     </select>
 

+ 6 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaiShouVideoGetMapper.xml

@@ -109,6 +109,12 @@
         group by signature
         order by stat_date desc
     </select>
+    <select id="getPhotoIdsByParams" resultType="cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet">
+        select distinct photo_id from ctop_kuaishou_video_get
+        where account_id = #{accountId}
+        and signature = #{signature}
+        and status = 0
+    </select>
 
 
 </mapper>

+ 2 - 2
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouStrategyMapper.xml

@@ -12,8 +12,8 @@
     </select>
 
     <select id="queryActiveAccount" resultType="java.lang.Long">
-        SELECT account_id FROM ctop_ai_kuaishou_auto_creative_account_info
-        WHERE status = 1
+        SELECT account_id FROM ctop_ai_kuaishou_advertiser_strategy
+        WHERE timer_task_status = 1
         GROUP BY account_id
     </select>
 </mapper>

+ 9 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaiShouCreativeService.java

@@ -1,6 +1,7 @@
 package cn.com.ctop.kuaishou.modules.batch.service;
 
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCreative;
+import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import java.util.List;
@@ -55,4 +56,12 @@ public interface IKuaiShouCreativeService extends IService<KuaiShouCreative> {
     void delAllCreativesByCampaignId(Long accountId, Long campaignId);
 
     List<KuaiShouCreative> queryCreativeInfoByCampaignId(Long accountId, Long campaignId);
+
+    KuaiShouCreative getCreativeByCreativeId(Long creativeId);
+
+    JSONArray getCreativeIds(Long accountId);
+
+    String convertMoString(String sMo);
+
+    List<KuaiShouCreative> getByParams(Long accountId, String photoId, Integer putStatus);
 }

+ 3 - 12
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouInterfaceService.java

@@ -8,7 +8,6 @@ import cn.com.ctop.kuaishou.modules.material.entity.KuaishouResultToken;
 import cn.com.ctop.kuaishou.modules.report.entity.*;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.google.gson.JsonArray;
 
 import java.text.ParseException;
 import java.util.Date;
@@ -21,7 +20,7 @@ import java.util.Map;
  */
 public interface IKuaishouInterfaceService {
 
-    KuaishouResultToken getAccessToken(String authCode, Integer agentType);
+    KuaishouResultToken getAccessToken(String authCode, Long appId);
 
 
     /**
@@ -152,7 +151,6 @@ public interface IKuaishouInterfaceService {
     void getCreativeList(CtopOauthToken token, Date startDate, Date endDate);
 
 
-
     /**
      * 根据组id,获取创意列表
      *
@@ -162,7 +160,7 @@ public interface IKuaishouInterfaceService {
      * @param endDate
      * @param timeFilterType
      */
-    JSONArray getCreativeList(CtopOauthToken token, Long unitId, Date startDate, Date endDate,int timeFilterType);
+    JSONArray getCreativeList(CtopOauthToken token, Long unitId, Date startDate, Date endDate, int timeFilterType);
 
 
     /**
@@ -359,7 +357,6 @@ public interface IKuaishouInterfaceService {
     void getCampaignList(CtopOauthToken token, Date startDate, Date endDate);
 
 
-
     /**
      * 获取计划列表,新增一个参数 按创建时间,还是更新时间进行筛选
      *
@@ -381,7 +378,6 @@ public interface IKuaishouInterfaceService {
     void getGroupList(CtopOauthToken token, Date startDate, Date endDate);
 
 
-
     /**
      * 获取指定广告计划下的广告组列表
      *
@@ -391,12 +387,7 @@ public interface IKuaishouInterfaceService {
      * @param endDate
      * @param time_filter_type
      */
-    JSONArray getGroupList(CtopOauthToken token, Long campaignId, Date startDate, Date endDate,int time_filter_type);
-
-
-
-
-
+    JSONArray getGroupList(CtopOauthToken token, Long campaignId, Date startDate, Date endDate, int time_filter_type);
 
 
     /**

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

@@ -16,6 +16,5 @@ public interface IKuaishouTemplateService extends IService<KuaishouTemplate> {
 
     JSONObject createTemplate(Long accountId, String accessToken, JSONObject requestJson);
 
-
     JSONObject updateTemplate(Long accountId, String accessToken, JSONObject requestJson);
 }

+ 91 - 3
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouCreativeServiceImpl.java

@@ -17,6 +17,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -31,9 +32,9 @@ import java.util.Map;
 @Slf4j
 @Service
 public class KuaiShouCreativeServiceImpl extends ServiceImpl<KuaiShouCreativeMapper, KuaiShouCreative> implements IKuaiShouCreativeService {
-    @Autowired
+    @Resource
     private KuaiShouCreativeMapper kuaiShouCreativeMapper;
-    @Autowired
+    @Resource
     private KuaiShouVideoGetMapper kuaiShouVideoGetMapper;
 
     @Override
@@ -195,7 +196,94 @@ public class KuaiShouCreativeServiceImpl extends ServiceImpl<KuaiShouCreativeMap
 
     @Override
     public List<KuaiShouCreative> queryCreativeInfoByCampaignId(Long accountId, Long campaignId) {
-        return kuaiShouCreativeMapper.queryCreativeInfoByCampaignId(accountId,campaignId);
+        return kuaiShouCreativeMapper.queryCreativeInfoByCampaignId(accountId, campaignId);
+    }
+
+    @Override
+    public KuaiShouCreative getCreativeByCreativeId(Long creativeId) {
+        QueryWrapper<KuaiShouCreative> creativeQueryWrapper = new QueryWrapper<>();
+        creativeQueryWrapper.eq("creative_id", creativeId);
+        creativeQueryWrapper.last("limit 1");
+        KuaiShouCreative creative = kuaiShouCreativeMapper.selectOne(creativeQueryWrapper);
+        return creative;
+    }
+
+    @Override
+    public JSONArray getCreativeIds(Long accountId) {
+        List<Long> creativeIds = kuaiShouCreativeMapper.getCreativeIds(accountId);
+        return JSONArray.parseArray(creativeIds.toString());
+    }
+
+    @Override
+    public synchronized String convertMoString(String sMo) {
+        if (Check.isNull(sMo)) {
+            return null;
+        }
+        String newString = null;
+        try {
+            if (sMo.contains(",")) {
+                return sMo.replace(',', ',');
+            } else if (sMo.contains("~")) {
+                newString = sMo.replace('~', '~');
+            } else if (sMo.contains("。")) {
+                newString = sMo.replace('。', '.');
+            } else if (sMo.contains(";")) {
+                newString = sMo.replace(';', ';');
+            } else if (sMo.contains("!")) {
+                newString = sMo.replace("!", "!");
+            } else if (sMo.contains("?")) {
+                newString = sMo.replace('?', '?');
+            } else if (sMo.contains(":")) {
+                newString = sMo.replace(':', ':');
+            } else if (sMo.contains("“")) {
+                newString = sMo.replace('“', '"');
+            } else if (sMo.contains("”")) {
+                newString = sMo.replace('”', '"');
+            } else if (sMo.contains("<")) {
+                newString = sMo.replace('>', '》').replace('<', '《');
+            } else if (sMo.contains(",")) {
+                newString = sMo.replace(',', ',');
+            } else if (sMo.contains(".")) {
+                newString = sMo.replace('.', '。');
+            } else if (sMo.contains(";")) {
+                newString = sMo.replace(';', ';');
+            } else if (sMo.contains("!")) {
+                newString = sMo.replace("!", "!");
+            } else if (sMo.contains("?")) {
+                newString = sMo.replace('?', '?');
+            } else if (sMo.contains(":")) {
+                newString = sMo.replace(':', ':');
+            } else if (sMo.contains(""")) {
+                newString = sMo.replace('"', '“');
+            } else if (sMo.contains(""")) {
+                newString = sMo.replace('"', '”');
+            } else if (sMo.contains("《")) {
+                newString = sMo.replace('》', '>').replace('《', '<');
+            } else if (sMo.contains("~")) {
+                newString = sMo.replace('~', '~');
+            } else {
+                newString = sMo;
+            }
+
+        } catch (Exception ex) {
+            return sMo;
+        }
+        return newString;
+    }
+
+    @Override
+    public List<KuaiShouCreative> getByParams(Long accountId, String photoId, Integer putStatus) {
+        QueryWrapper<KuaiShouCreative>queryWrapper =new QueryWrapper<>();
+        if(null!=accountId&&accountId!=0){
+            queryWrapper.eq("account_id",accountId);
+        }
+        if(null!=photoId&&!"".equals(photoId.trim())){
+            queryWrapper.eq("photo_id",photoId);
+        }
+        if(null!=putStatus&&putStatus!=0){
+            queryWrapper.eq("put_status",putStatus);
+        }
+        return this.list(queryWrapper);
     }
 
 

+ 18 - 18
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouUpdateServiceImpl.java

@@ -15,6 +15,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -25,20 +26,27 @@ import java.util.Map;
 @Slf4j
 @Service
 public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
-    @Autowired
+    @Resource
     private KuaiShouCampaignMapper campaignMapper;
-    @Autowired
+    @Resource
     private KuaiShouCampaignDayBudgetMapper campaignDayBudgetMapper;
-    @Autowired
+    @Resource
     private KuaiShouGroupMapper groupMapper;
     @Autowired
+    private IKuaiShouGroupService groupService;
+    @Resource
     private KuaiShouGroupDayBudgetMapper groupDayBudgetMapper;
-    @Autowired
+    @Resource
     private IKuaishouInterfaceService interfaceService;
-    @Autowired
+    @Resource
     private KuaiShouGroupBidMapper groupBidMapper;
-    @Autowired
+    @Resource
     private KuaiShouCampaignStatusMapper campaignStatusMapper;
+    @Resource
+    private KuaiShouCampaignMapper kuaiShouCampaignMapper;
+    @Resource
+    private KuaiShouCreativeMapper creativeMapper;
+
 
     @Override
     public Map<String, Object> updateCampaign(String token, Long advertiserId, Long campaignId, Long dayBudget, String loginId) {
@@ -105,6 +113,7 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
     }
 
 
+
     /**
      * 修改广告组预算
      *
@@ -114,9 +123,6 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
      * @param dayBudget
      * @return
      */
-    @Autowired
-    private IKuaiShouGroupService groupService;
-
     @Override
     public Map<String, Object> updateUnitDayBudget(String token, Long advertiserId, Long unitId, Long dayBudget, String loginId) {
         Map<String, Object> returnMap = new HashMap<>();
@@ -260,9 +266,6 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
      * @param putStatus
      * @return
      */
-    @Autowired
-    private KuaiShouCampaignMapper kuaiShouCampaignMapper;
-
     @Override
     public Map<String, Object> updateCampaignStatus(String token, Long advertiserId, Long campaignId, int putStatus, String loginId) {
         Map<String, Object> returnMap = new HashMap<>();
@@ -403,9 +406,6 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
      * @param putStatus
      * @return
      */
-    @Autowired
-    private KuaiShouCreativeMapper creativeMapper;
-
     @Override
     public Map<String, Object> updateCreativeStatus(String token, Long advertiserId, Long creativeId, int putStatus, String loginId) {
         Map<String, Object> returnMap = new HashMap<>();
@@ -477,7 +477,6 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
             header.put("Access-Token", token);
             header.put("Content-Type", "application/json");
             JSONObject params = new JSONObject();
-
             params.put("advertiser_id", advertiserId);
             String creativeId = requestJson.getString("creativeId");
             String creativeName = requestJson.getString("creativeName");
@@ -495,8 +494,9 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
             if (!Check.isNull(action_bar_text)) {
                 params.put("action_bar_text", action_bar_text);
             }
-
-
+            if (!Check.isNull(requestJson.getString("imageToken"))) {
+                params.put("image_token", requestJson.getString("imageToken"));
+            }
             String result = HttpUtils.httpPostRequest(url, params, header);
             JSONObject resultJson = JSONObject.parseObject(result);
             if (!Check.isNull(resultJson)) {

+ 1 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouBatchCreativePreviewServiceImpl.java

@@ -18,6 +18,7 @@ import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouMaterialUploadService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouBatchCreativePreviewService;
+import com.alibaba.fastjson.JSONObject;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;

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

@@ -2,11 +2,14 @@ package cn.com.ctop.kuaishou.modules.batch.service.impl;
 
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.entity.MaterialCutFrame;
+import cn.com.ctop.common.module.entity.OauthConfig;
 import cn.com.ctop.common.module.entity.UserAllocation;
 import cn.com.ctop.common.module.enums.MaterialEnum;
 import cn.com.ctop.common.module.service.IMaterialCutFrameService;
+import cn.com.ctop.common.module.service.IOauthConfigService;
 import cn.com.ctop.common.module.service.IUserAllocationService;
 import cn.com.ctop.common.module.utils.*;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouAccountCreativeOverrunInfoService;
 import cn.com.ctop.kuaishou.modules.batch.entity.*;
 import cn.com.ctop.kuaishou.modules.batch.entity.vo.ConvertVo;
 import cn.com.ctop.kuaishou.modules.batch.mapper.*;
@@ -198,7 +201,6 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
             JSONObject resultJson = JSONObject.parseObject(result);
             if (Check.isNull(resultJson)) {
                 return;
-
             }
             Integer code = resultJson.getInteger("code");
             String message = resultJson.getString("message");
@@ -1021,7 +1023,13 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                     if (!Check.isNull(dataJson)) {
                         Long unitId = dataJson.getLong("unit_id");
                         Thread.sleep(100);
-                        getKuaiShouGroupService.getGroupByUnitId(accessToken, advertiserId, unitId);
+                        Thread thread = new Thread() {
+                            @Override
+                            public void run() {
+                                getKuaiShouGroupService.getGroupByUnitId(accessToken, advertiserId, unitId);
+                            }
+                        };
+                        thread.start();
                         returnMap.put("code", 0);
                         returnMap.put("message", "success");
                         returnMap.put("unitId", unitId);
@@ -1870,20 +1878,18 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
      * @param authCode
      * @return
      */
+    @Autowired
+    private IOauthConfigService configService;
+
     @Override
-    public KuaishouResultToken getAccessToken(String authCode, Integer agentType) {
+    public KuaishouResultToken getAccessToken(String authCode, Long appId) {
         String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.AUTH_TOKEN;
         JSONObject requestJson = new JSONObject();
         requestJson.put("auth_code", authCode);
 
-        if (agentType == 1) { // 本代理商开户
-            requestJson.put("app_id", PropertiesUtils.getConfig("kuaishou_appid"));
-            requestJson.put("secret", PropertiesUtils.getConfig("kuaishou_secret"));
-        } else if (agentType == 0) {
-            requestJson.put("app_id", PropertiesUtils.getConfig("kuaishou_third_appid"));
-            requestJson.put("secret", PropertiesUtils.getConfig("kuaishou_third_secret"));
-        }
-
+        OauthConfig config = configService.getConfigByAppId(appId);
+        requestJson.put("app_id", config.getAppId());
+        requestJson.put("secret", config.getSecret());
         Map<String, String> headers = new HashMap<>();
         headers.put("Content-Type", " application/json");
         KuaishouResultToken kuaiShouResult = null;
@@ -2088,6 +2094,7 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                     }
 
                     if (code == 400001 && "/rest/openapi/v2/creative/create调用已超日限,次日可恢复调用".equals(resultJson.getString("message"))) {
+                        creativeOverrunInfoService.updateOverrunInfo(advertiserId);
                         overRunSendMessageService.creativeOverRunSendMessage(advertiserId, null);
                     }
                     log.error("创建广告创意失败,advertiser_id:{},返回信息:{},入参:{}", advertiserId, resultJson, requestJson, count + 1);
@@ -2119,6 +2126,8 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
 
     }
 
+    @Autowired
+    private IKuaishouAccountCreativeOverrunInfoService creativeOverrunInfoService;
 
     @Override
     public Map<String, Object> batchCreativeCreate(String accessToken, Long advertiserId, JSONObject requestJson, Integer count, String userId) {
@@ -2975,7 +2984,7 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                     @Override
                     public void run() {
                         List<MaterialCutFrame> cutFrames = cutFrameService.getListByVideoSignature(md5);
-                        if(null==cutFrames||cutFrames.isEmpty()){
+                        if (null == cutFrames || cutFrames.isEmpty()) {
                             videoGetService.getKeyFrame(token, accountId, md5, String.valueOf(photo_id));
                         }
                     }

+ 11 - 6
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouTemplateServiceImpl.java

@@ -46,6 +46,9 @@ public class KuaishouTemplateServiceImpl extends ServiceImpl<KuaishouTemplateMap
         JSONObject resultJson = JSONObject.parseObject(result);
         if (!Check.isNull(resultJson)) {
             Integer code = resultJson.getInteger("code");
+         /*   Map<String, Object> deleteMap = new HashMap<>();
+            deleteMap.put("account_id", accountId);
+            this.removeByMap(deleteMap);*/
             if (code == 0) {
                 JSONObject dataJson = resultJson.getJSONObject("data");
                 if (Check.isNull(dataJson)) {
@@ -339,19 +342,22 @@ public class KuaishouTemplateServiceImpl extends ServiceImpl<KuaishouTemplateMap
      */
     @Override
     public JSONObject updateTemplate(Long accountId, String accessToken, JSONObject requestJson) {
+        System.err.println(requestJson);
         JSONObject returnJson = new JSONObject();
         try {
             if (Check.isNull(requestJson.getString("templateName"))) {
                 throw new Exception("定向模板名称为必传项");
             }
+            if (Check.isNull(requestJson.getLong("templateId"))) {
+                throw new Exception("定向模板id为必传项");
+            }
 
             JSONObject param = new JSONObject();
             param.put("template_id", requestJson.getLong("templateId"));
             param.put("advertiser_id", accountId);
-            if(!Check.isNull(requestJson.getString("templateName"))){
+            if (!Check.isNull(requestJson.getString("templateName"))) {
                 param.put("template_name", requestJson.getString("templateName"));
             }
-
             JSONObject targetJson = new JSONObject();
             if (!Check.isNull(requestJson.getJSONArray("region"))) {
                 targetJson.put("region", requestJson.getJSONArray("region"));
@@ -449,15 +455,13 @@ public class KuaishouTemplateServiceImpl extends ServiceImpl<KuaishouTemplateMap
             if (!Check.isNull(targetJson)) {
                 param.put("target", targetJson);
             }
-
             Map<String, String> headers = new HashMap<String, String>();
             headers.put("Access-Token", accessToken);
             headers.put("Content-Type", " application/json");
-            System.err.println("入参:" + param.toJSONString());
             String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.TEMPLATE_UPDATE;
+            System.err.println("入参:" + param);
             String result = HttpUtils.kuaiShouhttpPostRequest(url, param.toJSONString(), headers);
             JSONObject resultJson = JSONObject.parseObject(result);
-            System.err.println("返回:" + resultJson.toJSONString());
             if (!Check.isNull(resultJson)) {
                 Integer code = resultJson.getInteger("code");
                 if (code == 0) {
@@ -468,8 +472,9 @@ public class KuaishouTemplateServiceImpl extends ServiceImpl<KuaishouTemplateMap
                         returnJson.put("templateId", data.getLong("template_id"));
                     }
                 } else {
+                    log.error("修改失败:{}", resultJson);
                     returnJson.put("code", -1);
-                    returnJson.put("message", returnJson.getString("message"));
+                    returnJson.put("message", resultJson.getString("message"));
                 }
             } else {
                 returnJson.put("code", -1);

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

@@ -76,7 +76,6 @@ public class KuaishouVideoRelateCreativesServiceImpl extends ServiceImpl<Kuaisho
             params.put("advertiser_id", accountId);
             params.put("photo_ids", photoIds);
             params.put("share_advertiser_ids", shareAdvertiserIds);
-            System.out.println(params);
             String result = HttpUtils.httpPostRequest(url, params, header);
             JSONObject resultJson = JSONObject.parseObject(result);
             if (!Check.isNull(resultJson)) {
@@ -158,7 +157,7 @@ public class KuaishouVideoRelateCreativesServiceImpl extends ServiceImpl<Kuaisho
         if(null == matNum||matNum == 0){
             matNum = 10;
         }
-        queryWrapper.eq("creative_count",0);
+        queryWrapper.le("creative_count",30);
         queryWrapper.orderByDesc("stat_date");
         queryWrapper.last("limit "+matNum);
         return this.list(queryWrapper);

+ 330 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/controller/KuaishouGroupExploreController.java

@@ -0,0 +1,330 @@
+package cn.com.ctop.kuaishou.modules.report.controller;
+
+import cn.com.ctop.common.module.annotation.AutoLog;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouGroupExplore;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouGroupExploreService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 广告组的加速探索报表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-02-02
+ */
+@Slf4j
+@Api(tags = "广告组的加速探索报表")
+@RestController
+@RequestMapping("/explore")
+public class KuaishouGroupExploreController {
+    @Autowired
+    private IKuaishouGroupExploreService kuaishouGroupExploreService;
+
+    /**
+     * 分页列表查询
+     *
+     * @param kuaishouGroupExplore
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索报表-分页列表查询")
+    @ApiOperation(value = "广告组的加速探索报表-分页列表查询", notes = "广告组的加速探索报表-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<KuaishouGroupExplore>> queryPageList(KuaishouGroupExplore kuaishouGroupExplore,
+                                                             @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                             @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+                                                             HttpServletRequest req) {
+        Result<IPage<KuaishouGroupExplore>> result = new Result<>();
+        QueryWrapper<KuaishouGroupExplore> queryWrapper = QueryGenerator.initQueryWrapper(kuaishouGroupExplore, req.getParameterMap());
+        Page<KuaishouGroupExplore> page = new Page<KuaishouGroupExplore>(pageNo, pageSize);
+        IPage<KuaishouGroupExplore> pageList = kuaishouGroupExploreService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     * 查询加速探索信息接口
+     *
+     * @param kuaishouGroupExplore
+     * @return
+     */
+    @AutoLog(value = "查询加速探索信息接口")
+    @ApiOperation(value = "查询加速探索信息接口", notes = "查询加速探索信息接口")
+    @PostMapping(value = "/unitExploreInfoGet")
+    public Result<Object> unitExploreInfoGet(@RequestBody JSONObject data) {
+        try {
+            return kuaishouGroupExploreService.unitExploreInfoGet(data);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return Result.error("操作失败");
+        }
+    }
+
+    /**
+     * 广告组的加速探索预算设置接口
+     *
+     * @param kuaishouGroupExplore
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索预算设置接口")
+    @ApiOperation(value = "广告组的加速探索预算设置接口", notes = "广告组的加速探索预算设置接口")
+    @PostMapping(value = "/unitExploreBudgetUpdate")
+    public Result<Object> unitExploreBudgetUpdate(@RequestBody JSONObject data) {
+        try {
+            return kuaishouGroupExploreService.unitExploreBudgetUpdate(data);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return Result.error("操作失败");
+        }
+    }
+
+    /**
+     * 暂停广告组的加速探索预算接口
+     *
+     * @param kuaishouGroupExplore
+     * @return
+     */
+    @AutoLog(value = "暂停广告组的加速探索预算接口")
+    @ApiOperation(value = "暂停广告组的加速探索预算接口", notes = "暂停广告组的加速探索预算接口")
+    @PostMapping(value = "/unitExploreStatusPause")
+    public Result<Object> unitExploreStatusPause(@RequestBody JSONObject data) {
+        try {
+            return kuaishouGroupExploreService.unitExploreStatusPause(data);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return Result.error("操作失败");
+        }
+    }
+
+    /**
+     * 查询广告组的加速探索报表接口
+     *
+     * @param kuaishouGroupExplore
+     * @return
+     */
+    @AutoLog(value = "查询广告组的加速探索报表接口")
+    @ApiOperation(value = "查询广告组的加速探索报表接口", notes = "查询广告组的加速探索报表接口")
+    @PostMapping(value = "/querySpeedExploreReport")
+    public Result<Object> querySpeedExploreReport(@RequestBody JSONObject data) {
+        try {
+            return kuaishouGroupExploreService.querySpeedExploreReport(data);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return Result.error("操作失败");
+        }
+    }
+
+
+    /**
+     * 添加
+     *
+     * @param kuaishouGroupExplore
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索报表-添加")
+    @ApiOperation(value = "广告组的加速探索报表-添加", notes = "广告组的加速探索报表-添加")
+    @PostMapping(value = "/add")
+    public Result<KuaishouGroupExplore> add(@RequestBody KuaishouGroupExplore kuaishouGroupExplore) {
+        Result<KuaishouGroupExplore> result = new Result<>();
+        try {
+            kuaishouGroupExploreService.save(kuaishouGroupExplore);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param kuaishouGroupExplore
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索报表-编辑")
+    @ApiOperation(value = "广告组的加速探索报表-编辑", notes = "广告组的加速探索报表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<KuaishouGroupExplore> edit(@RequestBody KuaishouGroupExplore kuaishouGroupExplore) {
+        Result<KuaishouGroupExplore> result = new Result<KuaishouGroupExplore>();
+        KuaishouGroupExplore kuaishouGroupExploreEntity = kuaishouGroupExploreService.getById(kuaishouGroupExplore.getId());
+        if (kuaishouGroupExploreEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = kuaishouGroupExploreService.updateById(kuaishouGroupExplore);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索报表-通过id删除")
+    @ApiOperation(value = "广告组的加速探索报表-通过id删除", notes = "广告组的加速探索报表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+        try {
+            kuaishouGroupExploreService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索报表-批量删除")
+    @ApiOperation(value = "广告组的加速探索报表-批量删除", notes = "广告组的加速探索报表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<KuaishouGroupExplore> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+        Result<KuaishouGroupExplore> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.kuaishouGroupExploreService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "广告组的加速探索报表-通过id查询")
+    @ApiOperation(value = "广告组的加速探索报表-通过id查询", notes = "广告组的加速探索报表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<KuaishouGroupExplore> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<KuaishouGroupExplore> result = new Result<>();
+        KuaishouGroupExplore kuaishouGroupExplore = kuaishouGroupExploreService.getById(id);
+        if (kuaishouGroupExplore == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(kuaishouGroupExplore);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<KuaishouGroupExplore> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                KuaishouGroupExplore kuaishouGroupExplore = JSON.parseObject(deString, KuaishouGroupExplore.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(kuaishouGroupExplore, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<KuaishouGroupExplore> pageList = kuaishouGroupExploreService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "广告组的加速探索报表列表");
+        mv.addObject(NormalExcelConstants.CLASS, KuaishouGroupExplore.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("广告组的加速探索报表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<KuaishouGroupExplore> listKuaishouGroupExplores = ExcelImportUtil.importExcel(file.getInputStream(), KuaishouGroupExplore.class, params);
+                kuaishouGroupExploreService.saveBatch(listKuaishouGroupExplores);
+                return Result.ok("文件导入成功!数据行数:" + listKuaishouGroupExplores.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 112 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouGroupExplore.java

@@ -0,0 +1,112 @@
+package cn.com.ctop.kuaishou.modules.report.entity;
+
+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.util.Date;
+
+/**
+ * 广告组的加速探索报表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-02-02
+ */
+@Data
+@TableName("ctop_kuaishou_group_explore")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_kuaishou_group_explore对象", description = "广告组的加速探索报表")
+public class KuaishouGroupExplore {
+
+    /**
+     * id
+     */
+    @TableId
+    @ApiModelProperty(value = "id")
+    private String 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 Long exploreBudget;
+    /**
+     * 优化目标
+     */
+    @Excel(name = "优化目标", width = 15)
+    @ApiModelProperty(value = "优化目标")
+    private Integer ocpxActionType;
+    /**
+     * 总消耗
+     */
+    @Excel(name = "总消耗", width = 15)
+    @ApiModelProperty(value = "总消耗")
+    private Long totalCharge;
+    /**
+     * 封面曝光数
+     */
+    @Excel(name = "封面曝光数", width = 15)
+    @ApiModelProperty(value = "封面曝光数")
+    private Long impression;
+    /**
+     * 素材曝光数
+     */
+    @Excel(name = "素材曝光数", width = 15)
+    @ApiModelProperty(value = "素材曝光数")
+    private Long click;
+    /**
+     * 封面点击数
+     */
+    @Excel(name = "封面点击数", width = 15)
+    @ApiModelProperty(value = "封面点击数")
+    private Long photoClick;
+    /**
+     * 转化数
+     */
+    @Excel(name = "转化数", width = 15)
+    @ApiModelProperty(value = "转化数")
+    private Long unifiedConversion;
+    /**
+     * 转化成本
+     */
+    @Excel(name = "转化成本", width = 15)
+    @ApiModelProperty(value = "转化成本")
+    private java.math.BigDecimal unitfiedConversionCost;
+    /**
+     * 创建时间
+     */
+    @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;
+}

+ 2 - 2
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouReportDailyAgent.java

@@ -41,13 +41,13 @@ public class KuaishouReportDailyAgent {
     @Excel(name = "账户ID", width = 15)
     @ApiModelProperty(value = "账户ID")
     @TableId(type = IdType.INPUT)
-    private java.lang.Integer accountId;
+    private java.lang.Long accountId;
     /**
      * 快手ID
      */
     @Excel(name = "快手ID", width = 15)
     @ApiModelProperty(value = "快手ID")
-    private java.lang.Integer kid;
+    private java.lang.Long kid;
     /**
      * 广告主名称
      */

+ 17 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/KuaishouGroupExploreMapper.java

@@ -0,0 +1,17 @@
+package cn.com.ctop.kuaishou.modules.report.mapper;
+
+import java.util.List;
+
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouGroupExplore;
+import org.apache.ibatis.annotations.Param;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 广告组的加速探索报表
+ * @author: jeecg-boot
+ * @date:   2021-02-02
+ * @cersion: V1.0
+ */
+public interface KuaishouGroupExploreMapper extends BaseMapper<KuaishouGroupExplore> {
+
+}

+ 14 - 14
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaiShouDailyAgentMapper.xml

@@ -6,24 +6,24 @@
     <!-- 代理商列表-->
     <select id="companyReport" resultType="cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyAgentSum">
         select
-        date_time as date,  <!-- 日期 -->
-        sum(charged_campaign_count) as costCampaignCount,  <!-- 有消费计划数 -->
-        sum(total_balance_in_yuan) as balance,  <!-- 总余额 -->
-        sum(total_charged_in_yuan) as cost,  <!-- 总消耗 -->
-        sum(real_charged_in_yuan) as xianjinCost,  <!-- 现金消耗 -->
-        sum(total_rebate_real_charged_in_yuan) as fandianCost,  <!-- 后返消耗 -->
-        sum(contract_rebate_real_charged_in_yuan) as kuangfanCost,  <!-- 框返消耗 -->
-        sum(direct_rebate_real_charged_in_yuan) as jiliCost,  <!-- 激励账户消耗 -->
-        sum(credit_real_charged_in_yuan) as xinyongCost,  <!-- 信用账户消耗 -->
-        sum(ad_photo_impression) as fengmianShowCount,  <!-- 封面曝光数 -->
-        sum(ad_photo_click) as fengmianClickCount,  <!-- 封面点击数 -->
-        sum(ad_item_impression) as sucaiShowCount,  <!-- 素材曝光数 -->
-        sum(ad_item_click) as convertCount,  <!-- 行为数 -->
+        date_time as date,
+        sum(charged_campaign_count) as costCampaignCount,
+        sum(total_balance_in_yuan) as balance,
+        sum(total_charged_in_yuan) as cost,
+        sum(real_charged_in_yuan) as xianjinCost,
+        sum(total_rebate_real_charged_in_yuan) as fandianCost,
+        sum(contract_rebate_real_charged_in_yuan) as kuangfanCost,
+        sum(direct_rebate_real_charged_in_yuan) as jiliCost,
+        sum(credit_real_charged_in_yuan) as xinyongCost,
+        sum(ad_photo_impression) as fengmianShowCount,
+        sum(ad_photo_click) as fengmianClickCount,
+        sum(ad_item_impression) as sucaiShowCount,
+        sum(ad_item_click) as convertCount,
         (case when sum(ad_photo_impression) != 0
         then sum(ad_photo_click) / sum(ad_photo_impression)
         else 0
         end
-        ) as fengmianClickRate,  <!-- 封面点击率 -->
+        ) as fengmianClickRate,
         (
         case when sum(ad_photo_click) != 0
         THEN sum(ad_item_click) / sum(ad_photo_click)

+ 5 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaishouGroupExploreMapper.xml

@@ -0,0 +1,5 @@
+<?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.kuaishou.modules.mapper.KuaishouGroupExploreMapper">
+
+</mapper>

+ 23 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/IKuaishouGroupExploreService.java

@@ -0,0 +1,23 @@
+package cn.com.ctop.kuaishou.modules.report.service;
+
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouGroupExplore;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.vo.Result;
+
+/**
+ * @Description: 广告组的加速探索报表
+ * @Author: jeecg-boot
+ * @Date:   2021-02-02
+ * @Version: V1.0
+ */
+public interface IKuaishouGroupExploreService extends IService<KuaishouGroupExplore> {
+
+    public Result<Object> unitExploreInfoGet(JSONObject data);
+
+    public Result<Object> unitExploreBudgetUpdate(JSONObject data);
+
+    public Result<Object> unitExploreStatusPause(JSONObject data);
+
+    public Result<Object> querySpeedExploreReport(JSONObject data);
+}

+ 221 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouGroupExploreServiceImpl.java

@@ -0,0 +1,221 @@
+package cn.com.ctop.kuaishou.modules.report.service.impl;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
+import cn.com.ctop.common.module.utils.PropertiesUtils;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouGroupExplore;
+import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouGroupExploreMapper;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouGroupExploreService;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 广告组的加速探索报表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-02-02
+ */
+@Slf4j
+@Service
+public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupExploreMapper, KuaishouGroupExplore> implements IKuaishouGroupExploreService {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+
+
+    /**
+     * 查询加速探索信息
+     *
+     * @param
+     * @throws
+     * @author ZHAOXA
+     */
+    @Override
+    public Result<Object> unitExploreInfoGet(JSONObject data) {
+        try {
+            Long accountId = data.getLong("accountId");
+            if (Check.isNull(accountId)) {
+                return Result.error("请选择广告主");
+            }
+            Long unitId = data.getLong("unitId");
+            if (Check.isNull(unitId)) {
+                return Result.error("请选择广告组");
+            }
+            CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.UNIT_EXPLORE_INFO_GET;
+            Map<String, String> header = new HashMap<>();
+            header.put("Access-Token", token.getAccessToken());
+            header.put("Content-Type", "application/json");
+            JSONObject params = new JSONObject();
+            params.put("advertiser_id", accountId);
+            params.put("unit_id", unitId);
+            String result = HttpUtils.httpPostRequest(url, params, header);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    return Result.ok(resultJson.getJSONObject("data"));
+                } else {
+                    log.info("查询加速探索信息失败,accountId:{},返回信息:{}", accountId, resultJson);
+                    return Result.error("查询加速探索信息失败," + resultJson.getString("message"));
+                }
+            }
+        } catch (Exception e) {
+            log.error("查询加速探索信息失败", e);
+        }
+        return Result.error("查询加速探索信息失败");
+    }
+
+    /**
+     * 广告组的加速探索预算设置
+     *
+     * @param
+     * @throws
+     * @author ZHAOXA
+     */
+    @Override
+    public Result<Object> unitExploreBudgetUpdate(JSONObject data) {
+        try {
+            Long accountId = data.getLong("accountId");
+            if (Check.isNull(accountId)) {
+                return Result.error("请选择广告主");
+            }
+            Long unitId = data.getLong("unitId");
+            if (Check.isNull(unitId)) {
+                return Result.error("请选择广告组");
+            }
+            Long exploreBudget = data.getLong("exploreBudget");
+            if (Check.isNull(exploreBudget)) {
+                return Result.error("请填写加速探索预算");
+            }
+            CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.UNIT_EXPLORE_BUDGET_UPDATE;
+            Map<String, String> header = new HashMap<>();
+            header.put("Access-Token", token.getAccessToken());
+            header.put("Content-Type", "application/json");
+            JSONObject params = new JSONObject();
+            params.put("advertiser_id", accountId);
+            params.put("unit_id", unitId);
+            params.put("explore_budget", exploreBudget);
+            String result = HttpUtils.httpPostRequest(url, params, header);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    return Result.ok(resultJson.getJSONObject("data"));
+                } else {
+                    log.info("广告组的加速探索预算设置失败,accountId:{},返回信息:{}", accountId, resultJson);
+                    return Result.error("广告组的加速探索预算设置失败," + resultJson.getString("message"));
+                }
+            }
+        } catch (Exception e) {
+            log.error("广告组的加速探索预算设置失败", e);
+        }
+        return Result.error("广告组的加速探索预算设置失败");
+    }
+
+    /**
+     * 暂停广告组的加速探索预算接口
+     *
+     * @param
+     * @throws
+     * @author ZHAOXA
+     */
+    @Override
+    public Result<Object> unitExploreStatusPause(JSONObject data) {
+        try {
+            Long accountId = data.getLong("accountId");
+            if (Check.isNull(accountId)) {
+                return Result.error("请选择广告主");
+            }
+            Long unitId = data.getLong("unitId");
+            if (Check.isNull(unitId)) {
+                return Result.error("请选择广告组");
+            }
+            CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.UNIT_EXPLORE_STATUS_PAUSE;
+            Map<String, String> header = new HashMap<>();
+            header.put("Access-Token", token.getAccessToken());
+            header.put("Content-Type", "application/json");
+            JSONObject params = new JSONObject();
+            params.put("advertiser_id", accountId);
+            params.put("unit_id", unitId);
+            String result = HttpUtils.httpPostRequest(url, params, header);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    return Result.ok(resultJson.getJSONObject("data"));
+                } else {
+                    log.info("暂停广告组的加速探索预算失败,accountId:{},返回信息:{}", accountId, resultJson);
+                    return Result.error("暂停广告组的加速探索预算失败," + resultJson.getString("message"));
+                }
+            }
+        } catch (Exception e) {
+            log.error("暂停广告组的加速探索预算失败", e);
+        }
+        return Result.error("暂停广告组的加速探索预算失败");
+    }
+
+    /**
+     * 查询广告组的加速探索报表接口
+     *
+     * @param
+     * @throws
+     * @author ZHAOXA
+     */
+    @Override
+    public Result<Object> querySpeedExploreReport(JSONObject data) {
+        try {
+            Long accountId = data.getLong("accountId");
+            if (Check.isNull(accountId)) {
+                return Result.error("请选择广告主");
+            }
+            Long unitId = data.getLong("unitId");
+            if (Check.isNull(unitId)) {
+                return Result.error("请选择广告组");
+            }
+            CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.QUERY_SPEED_EXPLORE_REPORT;
+            Map<String, String> header = new HashMap<>();
+            header.put("Access-Token", token.getAccessToken());
+            header.put("Content-Type", "application/json");
+            JSONObject params = new JSONObject();
+            params.put("advertiser_id", accountId);
+            params.put("unit_id", unitId);
+            String result = HttpUtils.httpPostRequest(url, params, header);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    JSONObject exploreJson = resultJson.getJSONObject("data");
+                    KuaishouGroupExplore kuaishouGroupExplore = JSONObject.toJavaObject(exploreJson, KuaishouGroupExplore.class);
+                    if (Check.isNull(kuaishouGroupExplore)) {
+                        return Result.error("查询失败,结果为空");
+                    }
+                    kuaishouGroupExplore.setAccountId(accountId);
+                    this.saveOrUpdate(kuaishouGroupExplore);
+                    return Result.ok("添加成功");
+                } else {
+                    log.info("查询广告组的加速探索报表失败,accountId:{},返回信息:{}", accountId, resultJson);
+                    return Result.error("查询广告组的加速探索报表失败," + resultJson.getString("message"));
+                }
+            }
+        } catch (Exception e) {
+            log.error("查询广告组的加速探索报表失败", e);
+        }
+        return Result.error("查询广告组的加速探索报表失败");
+    }
+
+
+}

+ 196 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/entity/BaseReportBytedanceVideoDaily.java

@@ -0,0 +1,196 @@
+package cn.com.ctop.toutiao.modules.link.entity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+/**
+ * 头条视频报表源数据
+ */
+@Data
+@TableName("base_report_bytedance_video_daily")
+public class BaseReportBytedanceVideoDaily {
+    
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	/**账户id*/
+	private Long accountId;
+	/**md5*/
+	private Long materialId;
+	/**数据起始时间*/
+	private String statDatetime;
+	/**总花费*/
+	private BigDecimal cost;
+	/**点击量*/
+	private Long click;
+	/**应用下载-激活*/
+	private Long active;
+	/**应用下载-安卓下载完成*/
+	private Long downloadFinish;
+	/**应用下载-安卓下载开始*/
+	private Long downloadStart;
+	/**应用下载-安卓安装完成*/
+	private Long installFinish;
+	/**应用下载-注册*/
+	private Long register;
+	/**应用下载-付费数*/
+	private Long payCount;
+	/**应用下载-到达uv*/
+	private Long inAppUv;
+	/**应用下载-详情页到站uv*/
+	private Long inAppDetailUv;
+	/**应用下载-加入购物车*/
+	private Long inAppCart;
+	/**应用下载-提交订单*/
+	private Long inAppOrder;
+	/**应用下载-付费*/
+	private Long inAppPay;
+	/**落地页-电话拨打数*/
+	private Long phone;
+	/**表单提交数*/
+	private Long form;
+	/**落地页-地图搜索*/
+	private Long mapSearch;
+	/**落地页-按钮button*/
+	private Long button;
+	/**落地页-关键页面浏览*/
+	private Long viewMaterial;
+	/**落地页-QQ咨询数*/
+	private Long qq;
+	/**落地页-抽奖数*/
+	private Long lottery;
+	/**落地页-投票*/
+	private Long vote;
+	/**落地页-页面跳转*/
+	private Long redirect;
+	/**落地页-商品购买*/
+	private Long shopping;
+	/**落地页-在线咨询*/
+	private Long consult;
+	/**落地页-微信*/
+	private Long wechat;
+	/**落地页-智能电话确认拨打*/
+	private Long phoneConfirm;
+	/**落地页-智能电话确认接通*/
+	private Long phoneConnect;
+	/**落地页-智能电话有效咨询*/
+	private Long consultEffective;
+	/**视频-总播放*/
+	private Long totalPlay;
+	/**视频-有效播放*/
+	private Long validPlay;
+	/**视频-wifi播放*/
+	private Long wifiPlay;
+	/**视频-播放25%进度率*/
+	private BigDecimal play25FeedBreakRate;
+	/**视频-播放25%进度总数*/
+	private Long play25FeedBreak;
+	/**视频-播放50%进度总数*/
+	private Long play50FeedBreak;
+	/**视频-播放75%进度总数*/
+	private Long play75FeedBreak;
+	/**视频-播放100%进度总数*/
+	private Long play100FeedBreak;
+	/**附加创意-电话按钮*/
+	private Long advancedCreativePhoneClick;
+	/**附加创意-在线咨询*/
+	private Long advancedCreativeCounselClick;
+	/**附加创意-表单提交*/
+	private Long advancedCreativeFormClick;
+	/**互动数据-分享数*/
+	private Long shareMaterial;
+	/**互动数据-评论数*/
+	private Long commentMaterial;
+	/**互动数据-新增关注数*/
+	private Long follow;
+	/**互动数据-主页访问量*/
+	private Long homeVisited;
+	/**互动数据-挑战赛查看数*/
+	private Long iesChallengeClick;
+	/**互动数据-音乐查看数*/
+	private Long iesMusicClick;
+	/**次留数*/
+	private Long nextDayOpen;
+	/**次留率*/
+	private BigDecimal nextDayOpenRate;
+	/**次留成本*/
+	private BigDecimal nextDayOpenCost;
+	/**activePayAmount*/
+	private Long activePayAmount;
+	/**视频数据-有效播放成本*/
+	private BigDecimal validPlayCost;
+	/**附加创意-附加创意卡券领取*/
+	private Long advancedCreativeCouponAddition;
+	/**convertMaterial*/
+	private Long convertMaterial;
+	/**应用下载广告数据-付费成本*/
+	private BigDecimal activePayCost;
+	/**落地页转化数据-下载开始*/
+	private Long download;
+	/**cpc*/
+	private BigDecimal cpc;
+	/**互动数据-POI点击数*/
+	private Long locationClick;
+	/**	视频数据-播完率*/
+	private BigDecimal playOverRate;
+	/**展现数据-点击率*/
+	private BigDecimal ctr;
+	/**cpm*/
+	private BigDecimal cpm;
+	/**视频数据-WiFi播放占比*/
+	private BigDecimal wifiPlayRate;
+	/**互动数据-点赞数*/
+	private Long likeMaterial;
+	/**应用下载广告数据-激活成本*/
+	private BigDecimal activeCost;
+	/**应用下载广告数据-关键行为成本*/
+	private BigDecimal gameAddictionCost;
+	/**应用下载广告数据-关键行为数*/
+	private Long gameAddiction;
+	/**应用下载广告数据-激活率*/
+	private BigDecimal activeRate;
+	/**	应用下载广告数据-关键行为率*/
+	private BigDecimal gameAddictionRate;
+	/**应用下载广告数据-注册率*/
+	private BigDecimal activeRegisterRate;
+	/**应用下载广告数据-安卓下载完成成本*/
+	private BigDecimal downloadFinishCost;
+	/**应用下载广告数据-注册成本*/
+	private BigDecimal activeRegisterCost;
+	/**展示数*/
+	private Long materialShow;
+	/**转化数据-转化率*/
+	private BigDecimal convertRate;
+	/**应用下载广告数据-安卓下载完成率*/
+	private BigDecimal downloadFinishRate;
+	/**应用下载广告数据-安卓安装完成率*/
+	private BigDecimal installFinishRate;
+	/**	落地页转化数据-建站卡券领取*/
+	private Long coupon;
+	/**落地页转化数据-卡券页领取*/
+	private Long couponSinglePage;
+	/**playOver*/
+	private Long playOver;
+	/**应用下载广告数据-安卓下载开始成本*/
+	private BigDecimal downloadStartCost;
+	/**落地页转化数据-短信咨询*/
+	private Long message;
+	/**视频数据-有效播放率*/
+	private BigDecimal validPlayRate;
+	/**视频数据-平均单次播放时长*/
+	private BigDecimal averagePlayTimePerPlay;
+	/**转化数据-转化成本*/
+	private BigDecimal convertCost;
+	/**应用下载广告数据-安卓安装完成成本*/
+	private BigDecimal installFinishCost;
+	/**应用下载广告数据-安卓下载开始率*/
+	private BigDecimal downloadStartRate;
+	/**createTime*/
+	private Date createTime;
+	/**updateTime*/
+	private Date updateTime;
+}

+ 436 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/entity/ETLReportBytedanceVideo.java

@@ -0,0 +1,436 @@
+package cn.com.ctop.toutiao.modules.link.entity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import org.jeecgframework.poi.excel.annotation.Excel;
+
+/**
+ * 头条视频报表ETL
+ */
+@Data
+@TableName("etl_report_bytedance_video")
+public class ETLReportBytedanceVideo {
+    
+	/**id*/
+	@TableId(type = IdType.AUTO)
+	private Long id;
+	/**materialId*/
+	@Excel(name = "materialId", width = 15)
+    @ApiModelProperty(value = "materialId")
+	private Long materialId;
+
+	private String materialName;
+	/**视频唯一标识*/
+	private String md5;
+
+	private String url;
+
+	private String toutiaoUrl;
+
+	private String coverUrl;
+
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
+	private Long accountId;
+
+	private String accountName;
+	/**项目id*/
+	@Excel(name = "项目id", width = 15)
+    @ApiModelProperty(value = "项目id")
+	private Long projectId;
+	/**项目名称*/
+	@Excel(name = "项目名称", width = 15)
+    @ApiModelProperty(value = "项目名称")
+	private String projectName;
+	/**项目id*/
+	@Excel(name = "项目id", width = 15)
+    @ApiModelProperty(value = "项目id")
+	private Long productId;
+	/**产品名称*/
+	@Excel(name = "产品名称", width = 15)
+    @ApiModelProperty(value = "产品名称")
+	private String productName;
+	/**广告主id*/
+	@Excel(name = "广告主id", width = 15)
+    @ApiModelProperty(value = "广告主id")
+	private String advertiserId;
+	/**广告主名称*/
+	@Excel(name = "广告主名称", width = 15)
+    @ApiModelProperty(value = "广告主名称")
+	private String advertiserName;
+	/**剪辑id*/
+	@Excel(name = "剪辑id", width = 15)
+    @ApiModelProperty(value = "剪辑id")
+	private String clipId;
+	/**剪辑名称*/
+	@Excel(name = "剪辑名称", width = 15)
+    @ApiModelProperty(value = "剪辑名称")
+	private String clipName;
+	/**拍摄id*/
+	@Excel(name = "拍摄id", width = 15)
+    @ApiModelProperty(value = "拍摄id")
+	private String shotId;
+	/**拍摄名称*/
+	@Excel(name = "拍摄名称", width = 15)
+    @ApiModelProperty(value = "拍摄名称")
+	private String shotName;
+	/**编导id*/
+	@Excel(name = "编导id", width = 15)
+    @ApiModelProperty(value = "编导id")
+	private String planId;
+	/**编导名称*/
+	@Excel(name = "编导名称", width = 15)
+    @ApiModelProperty(value = "编导名称")
+	private String planName;
+	/**materialCreateTime*/
+	private String materialCreateTime;
+	/**数据起始时间*/
+	@Excel(name = "数据起始时间", width = 15)
+    @ApiModelProperty(value = "数据起始时间")
+	private String statDatetime;
+	/**点击量*/
+	@Excel(name = "点击量", width = 15)
+    @ApiModelProperty(value = "点击量")
+	private Long click;
+	/**总花费*/
+	@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 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 viewMaterial;
+	/**落地页-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;
+	/**视频-播放25%进度率*/
+	@Excel(name = "视频-播放25%进度率", width = 15)
+    @ApiModelProperty(value = "视频-播放25%进度率")
+	private BigDecimal play25FeedBreakRate;
+	/**视频-播放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 shareMaterial;
+	/**互动数据-评论数*/
+	@Excel(name = "互动数据-评论数", width = 15)
+    @ApiModelProperty(value = "互动数据-评论数")
+	private Long commentMaterial;
+	/**互动数据-新增关注数*/
+	@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 Long nextDayOpen;
+	/**次留率*/
+	@Excel(name = "次留率", width = 15)
+    @ApiModelProperty(value = "次留率")
+	private BigDecimal nextDayOpenRate;
+	/**次留成本*/
+	@Excel(name = "次留成本", width = 15)
+    @ApiModelProperty(value = "次留成本")
+	private BigDecimal nextDayOpenCost;
+	/**activePayAmount*/
+	@Excel(name = "activePayAmount", width = 15)
+    @ApiModelProperty(value = "activePayAmount")
+	private Long activePayAmount;
+	/**视频数据-有效播放成本*/
+	@Excel(name = "视频数据-有效播放成本", width = 15)
+    @ApiModelProperty(value = "视频数据-有效播放成本")
+	private BigDecimal validPlayCost;
+	/**附加创意-附加创意卡券领取*/
+	@Excel(name = "附加创意-附加创意卡券领取", width = 15)
+    @ApiModelProperty(value = "附加创意-附加创意卡券领取")
+	private Long advancedCreativeCouponAddition;
+	/**convertMaterial*/
+	@Excel(name = "convertMaterial", width = 15)
+    @ApiModelProperty(value = "convertMaterial")
+	private Long convertMaterial;
+	/**应用下载广告数据-付费成本*/
+	@Excel(name = "应用下载广告数据-付费成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-付费成本")
+	private BigDecimal activePayCost;
+	/**落地页转化数据-下载开始*/
+	@Excel(name = "落地页转化数据-下载开始", width = 15)
+    @ApiModelProperty(value = "落地页转化数据-下载开始")
+	private Long download;
+	/**cpc*/
+	@Excel(name = "cpc", width = 15)
+    @ApiModelProperty(value = "cpc")
+	private BigDecimal cpc;
+	/**互动数据-POI点击数*/
+	@Excel(name = "互动数据-POI点击数", width = 15)
+    @ApiModelProperty(value = "互动数据-POI点击数")
+	private Long locationClick;
+	/**	视频数据-播完率*/
+	@Excel(name = "	视频数据-播完率", width = 15)
+    @ApiModelProperty(value = "	视频数据-播完率")
+	private BigDecimal playOverRate;
+	/**展现数据-点击率*/
+	@Excel(name = "展现数据-点击率", width = 15)
+    @ApiModelProperty(value = "展现数据-点击率")
+	private BigDecimal ctr;
+	/**cpm*/
+	@Excel(name = "cpm", width = 15)
+    @ApiModelProperty(value = "cpm")
+	private BigDecimal cpm;
+	/**视频数据-WiFi播放占比*/
+	@Excel(name = "视频数据-WiFi播放占比", width = 15)
+    @ApiModelProperty(value = "视频数据-WiFi播放占比")
+	private BigDecimal wifiPlayRate;
+	/**互动数据-点赞数*/
+	@Excel(name = "互动数据-点赞数", width = 15)
+    @ApiModelProperty(value = "互动数据-点赞数")
+	private Long likeMaterial;
+	/**应用下载广告数据-激活成本*/
+	@Excel(name = "应用下载广告数据-激活成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-激活成本")
+	private BigDecimal activeCost;
+	/**应用下载广告数据-关键行为成本*/
+	@Excel(name = "应用下载广告数据-关键行为成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-关键行为成本")
+	private BigDecimal gameAddictionCost;
+	/**应用下载广告数据-关键行为数*/
+	@Excel(name = "应用下载广告数据-关键行为数", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-关键行为数")
+	private Long gameAddiction;
+	/**应用下载广告数据-激活率*/
+	@Excel(name = "应用下载广告数据-激活率", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-激活率")
+	private BigDecimal activeRate;
+	/**	应用下载广告数据-关键行为率*/
+	@Excel(name = "	应用下载广告数据-关键行为率", width = 15)
+    @ApiModelProperty(value = "	应用下载广告数据-关键行为率")
+	private BigDecimal gameAddictionRate;
+	/**应用下载广告数据-注册率*/
+	@Excel(name = "应用下载广告数据-注册率", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-注册率")
+	private BigDecimal activeRegisterRate;
+	/**应用下载广告数据-安卓下载完成成本*/
+	@Excel(name = "应用下载广告数据-安卓下载完成成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-安卓下载完成成本")
+	private BigDecimal downloadFinishCost;
+	/**应用下载广告数据-注册成本*/
+	@Excel(name = "应用下载广告数据-注册成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-注册成本")
+	private BigDecimal activeRegisterCost;
+	/**materailShow*/
+	@Excel(name = "materailShow", width = 15)
+    @ApiModelProperty(value = "materailShow")
+	private Long materailShow;
+	/**转化数据-转化率*/
+	@Excel(name = "转化数据-转化率", width = 15)
+    @ApiModelProperty(value = "转化数据-转化率")
+	private BigDecimal convertRate;
+	/**应用下载广告数据-安卓下载完成率*/
+	@Excel(name = "应用下载广告数据-安卓下载完成率", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-安卓下载完成率")
+	private BigDecimal downloadFinishRate;
+	/**应用下载广告数据-安卓安装完成率*/
+	@Excel(name = "应用下载广告数据-安卓安装完成率", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-安卓安装完成率")
+	private BigDecimal installFinishRate;
+	/**	落地页转化数据-建站卡券领取*/
+	@Excel(name = "	落地页转化数据-建站卡券领取", width = 15)
+    @ApiModelProperty(value = "	落地页转化数据-建站卡券领取")
+	private Long coupon;
+	/**落地页转化数据-卡券页领取*/
+	@Excel(name = "落地页转化数据-卡券页领取", width = 15)
+    @ApiModelProperty(value = "落地页转化数据-卡券页领取")
+	private Long couponSinglePage;
+	/**playOver*/
+	@Excel(name = "playOver", width = 15)
+    @ApiModelProperty(value = "playOver")
+	private Long playOver;
+	/**应用下载广告数据-安卓下载开始成本*/
+	@Excel(name = "应用下载广告数据-安卓下载开始成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-安卓下载开始成本")
+	private BigDecimal downloadStartCost;
+	/**落地页转化数据-短信咨询*/
+	@Excel(name = "落地页转化数据-短信咨询", width = 15)
+    @ApiModelProperty(value = "落地页转化数据-短信咨询")
+	private Long message;
+	/**视频数据-有效播放率*/
+	@Excel(name = "视频数据-有效播放率", width = 15)
+    @ApiModelProperty(value = "视频数据-有效播放率")
+	private BigDecimal validPlayRate;
+	/**视频数据-平均单次播放时长*/
+	@Excel(name = "视频数据-平均单次播放时长", width = 15)
+    @ApiModelProperty(value = "视频数据-平均单次播放时长")
+	private BigDecimal averagePlayTimePerPlay;
+	/**转化数据-转化成本*/
+	@Excel(name = "转化数据-转化成本", width = 15)
+    @ApiModelProperty(value = "转化数据-转化成本")
+	private BigDecimal convertCost;
+	/**应用下载广告数据-安卓安装完成成本*/
+	@Excel(name = "应用下载广告数据-安卓安装完成成本", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-安卓安装完成成本")
+	private BigDecimal installFinishCost;
+	/**应用下载广告数据-安卓下载开始率*/
+	@Excel(name = "应用下载广告数据-安卓下载开始率", width = 15)
+    @ApiModelProperty(value = "应用下载广告数据-安卓下载开始率")
+	private BigDecimal downloadStartRate;
+	/**createTime*/
+    @ApiModelProperty(value = "createTime")
+	private Date createTime;
+	/**updateTime*/
+    @ApiModelProperty(value = "updateTime")
+	private Date updateTime;
+}

+ 11 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/BaseReportBytedanceVideoDailyMapper.java

@@ -0,0 +1,11 @@
+package cn.com.ctop.toutiao.modules.link.mapper;
+
+import cn.com.ctop.toutiao.modules.link.entity.BaseReportBytedanceVideoDaily;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * 头条视频报表源数据
+ */
+public interface BaseReportBytedanceVideoDailyMapper extends BaseMapper<BaseReportBytedanceVideoDaily> {
+
+}

+ 29 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/ETLReportBytedanceVideoMapper.java

@@ -0,0 +1,29 @@
+package cn.com.ctop.toutiao.modules.link.mapper;
+
+import cn.com.ctop.toutiao.modules.link.entity.ETLReportBytedanceVideo;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 头条视频报表ETL
+ */
+public interface ETLReportBytedanceVideoMapper extends BaseMapper<ETLReportBytedanceVideo> {
+
+    //根据material_id查询MD5、头条视频链接
+    JSONObject queryVideoInfoByMaterialId(@Param("materialId") Long materialId);
+    //根据MD5查询视频信息
+    JSONObject queryMaterialVideoByMd5(@Param("md5") String md5);
+
+    JSONObject queryMaterialVideoByMd5Old(@Param("md5") String md5);
+
+    //根据MD5查询素材关联人信息
+    JSONObject queryRelatePersonByMd5(@Param("md5") String md5);
+
+    JSONObject queryRelatePersonByMd5Old(@Param("md5") String md5);
+
+    //根据accountId 查询项目、产品、广告主信息
+    JSONObject queryAccountDetailByAccountId(@Param("accountId") Long accountId);
+}

+ 5 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/xml/BaseReportBytedanceVideoDailyMapper.xml

@@ -0,0 +1,5 @@
+<?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.toutiao.modules.link.mapper.BaseReportBytedanceVideoDailyMapper">
+
+</mapper>

+ 79 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/mapper/xml/ETLReportBytedanceVideoMapper.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.toutiao.modules.link.mapper.ETLReportBytedanceVideoMapper">
+    <select id="queryVideoInfoByMaterialId"  resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            signature AS md5,
+            video_url AS url
+        FROM
+            ctop_bytedance_video_info
+        WHERE
+            material_id = #{materialId}
+        limit 1
+    </select>
+    <select id="queryMaterialVideoByMd5"  resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            `name`  as materialName,
+            url,
+            cover_url coverUrl,
+            create_time as createTime
+        FROM
+            ctop_material_video_info
+        WHERE
+            md5 = #{md5}
+        LIMIT 1
+    </select>
+    <select id="queryMaterialVideoByMd5Old"  resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            material_name as materialName,
+            url,
+            cover_url coverUrl,
+            create_time as createTime
+        FROM
+            ctop_material_info
+        WHERE
+            code = #{md5}
+        LIMIT 1
+    </select>
+    <select id="queryRelatePersonByMd5"  resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            clip_id clipId,
+            clip_name clipaname,
+            shot_id shotId,
+            shot_name shotName,
+            plan_id planId,
+            plan_name planName
+        FROM
+            ctop_material_video_author
+        WHERE
+            video_md5 = #{md5}
+        LIMIT 1
+    </select>
+    <select id="queryRelatePersonByMd5Old"  resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            clip_id clipId,
+            (select realname from sys_user where id=clip_id) as clipaname,
+            shot_id shotId,
+            (select realname from sys_user where id=shot_id) as shotName,
+            plan_id planId,
+            (select realname from sys_user where id=plan_id) as planName
+        FROM
+            ctop_material_ascription
+        WHERE
+            code = #{md5}
+        LIMIT 1
+    </select>
+    <select id="queryAccountDetailByAccountId"  resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            t1.advertiser_id as advertiserId,
+            (SELECT `name` from ctop_advertiser where id=t1.advertiser_id limit 1) as advertiserName,
+            project_id as projectId,
+            (SELECT `project_name` from ctop_project where id=t1.project_id limit 1) as projectName,
+            auth_name as accountName
+        FROM
+            ctop_user_allocation t1
+        WHERE
+            account_id = #{accountId}
+        LIMIT 1
+    </select>
+</mapper>

+ 11 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/IBaseReportBytedanceVideoDailyService.java

@@ -0,0 +1,11 @@
+package cn.com.ctop.toutiao.modules.link.service;
+
+import cn.com.ctop.toutiao.modules.link.entity.BaseReportBytedanceVideoDaily;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *  头条视频报表源数据
+ */
+public interface IBaseReportBytedanceVideoDailyService extends IService<BaseReportBytedanceVideoDaily> {
+
+}

+ 17 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/IETLReportBytedanceVideoService.java

@@ -0,0 +1,17 @@
+package cn.com.ctop.toutiao.modules.link.service;
+
+import cn.com.ctop.toutiao.modules.link.entity.BaseReportBytedanceVideoDaily;
+import cn.com.ctop.toutiao.modules.link.entity.ETLReportBytedanceVideo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * 头条视频报表ETL
+ */
+public interface IETLReportBytedanceVideoService extends IService<ETLReportBytedanceVideo> {
+
+    List<BaseReportBytedanceVideoDaily> listByStatDate(String statDate);
+
+    void cleanETL(String statDate);
+}

+ 15 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/impl/BaseReportBytedanceVideoDailyServiceImpl.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.toutiao.modules.link.service.impl;
+
+import cn.com.ctop.toutiao.modules.link.entity.BaseReportBytedanceVideoDaily;
+import cn.com.ctop.toutiao.modules.link.mapper.BaseReportBytedanceVideoDailyMapper;
+import cn.com.ctop.toutiao.modules.link.service.IBaseReportBytedanceVideoDailyService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * 头条视频报表源数据
+ */
+@Service
+public class BaseReportBytedanceVideoDailyServiceImpl extends ServiceImpl<BaseReportBytedanceVideoDailyMapper, BaseReportBytedanceVideoDaily> implements IBaseReportBytedanceVideoDailyService {
+
+}

+ 95 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/link/service/impl/ETLReportBytedanceVideoServiceImpl.java

@@ -0,0 +1,95 @@
+package cn.com.ctop.toutiao.modules.link.service.impl;
+
+import cn.com.ctop.toutiao.modules.link.entity.BaseReportBytedanceVideoDaily;
+import cn.com.ctop.toutiao.modules.link.entity.ETLReportBytedanceVideo;
+import cn.com.ctop.toutiao.modules.link.mapper.ETLReportBytedanceVideoMapper;
+import cn.com.ctop.toutiao.modules.link.service.IBaseReportBytedanceVideoDailyService;
+import cn.com.ctop.toutiao.modules.link.service.IETLReportBytedanceVideoService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+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.ArrayList;
+import java.util.List;
+
+/**
+ * 头条视频报表ETL
+ */
+@Slf4j
+@Service
+public class ETLReportBytedanceVideoServiceImpl extends ServiceImpl<ETLReportBytedanceVideoMapper, ETLReportBytedanceVideo> implements IETLReportBytedanceVideoService {
+
+    @Autowired
+    IBaseReportBytedanceVideoDailyService baseReportBytedanceVideoDailyService;
+
+    @Autowired
+    ETLReportBytedanceVideoMapper etlReportBytedanceVideoMapper;
+
+    @Override
+    public List<BaseReportBytedanceVideoDaily> listByStatDate(String statDate) {
+        QueryWrapper<BaseReportBytedanceVideoDaily>  queryWrapper= new QueryWrapper<>();
+        queryWrapper.eq("stat_datetime",statDate);
+        return baseReportBytedanceVideoDailyService.list(queryWrapper);
+    }
+
+    @Override
+    public void cleanETL(String statDate) {
+        List<BaseReportBytedanceVideoDaily> source = listByStatDate(statDate);
+        if(source.isEmpty()){
+            XxlJobHelper.log("头条数据报表清洗ETL异常,请检查数据源");
+        }
+        List<ETLReportBytedanceVideo> batch = new ArrayList<>();
+        source.forEach(it->{
+            JSONObject videoInfo= etlReportBytedanceVideoMapper.queryVideoInfoByMaterialId(it.getMaterialId());
+            if(null==videoInfo||videoInfo.isEmpty()){
+                XxlJobHelper.log("头条数据报表清洗ETL异常,未关联到video_info,materialId:{}",it.getMaterialId());
+            }else {
+                //TODO 暂时从老数据库查询,新素材库怕同步数据有偏差
+                //JSONObject materialVideo= etlReportBytedanceVideoMapper.queryMaterialVideoByMd5(videoInfo.getString("md5"));
+                JSONObject materialVideo= etlReportBytedanceVideoMapper.queryMaterialVideoByMd5Old(videoInfo.getString("md5"));
+                //JSONObject relatePerson=etlReportBytedanceVideoMapper.queryRelatePersonByMd5(videoInfo.getString("md5"));
+                JSONObject relatePerson=etlReportBytedanceVideoMapper.queryRelatePersonByMd5Old(videoInfo.getString("md5"));
+
+                JSONObject accountDetail=etlReportBytedanceVideoMapper.queryAccountDetailByAccountId(it.getAccountId());
+                ETLReportBytedanceVideo temp = JSONObject.toJavaObject(JSONObject.parseObject(JSON.toJSON(it).toString()),ETLReportBytedanceVideo.class);
+                temp.setMd5(videoInfo.getString("md5"));
+                temp.setToutiaoUrl(videoInfo.getString("url"));
+                if(null!=materialVideo&&!materialVideo.isEmpty()) {
+                    temp.setUrl(materialVideo.getString("url"));
+                    temp.setCoverUrl(materialVideo.getString("coverUrl"));
+                    temp.setMaterialCreateTime(materialVideo.getDate("creteTime").toString());
+                }
+                if(null!=accountDetail&&!accountDetail.isEmpty()){
+                    temp.setAccountName(accountDetail.getString("accountName"));
+                    temp.setProjectId(accountDetail.getLong("projectId"));
+                    temp.setProjectName(accountDetail.getString("projectName"));
+                    temp.setProductId(accountDetail.getLong("productId"));
+                    temp.setProductName(accountDetail.getString("productName"));
+                    temp.setAdvertiserId(accountDetail.getString("advertiserId"));
+                    temp.setAdvertiserName(accountDetail.getString("advertiserName"));
+                }
+                if(null!=relatePerson&&!relatePerson.isEmpty()){
+                    temp.setClipId(relatePerson.getString("clipId"));
+                    temp.setClipName(relatePerson.getString("clipName"));
+                    temp.setShotId(relatePerson.getString("shotId"));
+                    temp.setShotName(relatePerson.getString("shotName"));
+                    temp.setPlanId(relatePerson.getString("planId"));
+                    temp.setPlanName(relatePerson.getString("planName"));
+                }
+                batch.add(temp);
+            }
+        });
+        boolean result = this.saveBatch(batch);
+        if(result){
+            XxlJobHelper.log("头条数据报表清洗成功,数据条数:{}",batch.size());
+        }else {
+            XxlJobHelper.log("头条数据报表清洗入库失败请重试,数据条数:{}",batch.size());
+        }
+    }
+
+}

+ 25 - 43
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/mapper/xml/BytedanceVideoReportMapper.xml

@@ -3,20 +3,19 @@
 <mapper namespace="cn.com.ctop.toutiao.modules.report.mapper.BytedanceVideoReportMapper">
 
     <select id="queryVideoReportBy" resultType="com.alibaba.fastjson.JSONObject">
-        SELECT * from (SELECT
-        t1.signature,
-        t1.video_url as url,
-        IFNULL((SELECT u.realname FROM ctop_material_ascription t3 LEFT JOIN sys_user u on t3.clip_id=u.id where t3.material_id=t1.signature limit 1),'') AS clip,
-        IFNULL((SELECT u.realname FROM ctop_material_ascription t3 LEFT JOIN sys_user u on t3.shot_id=u.id where t3.material_id=t1.signature limit 1),'') AS shot,
-        IFNULL((SELECT u.realname FROM ctop_material_ascription t3 LEFT JOIN sys_user u on t3.plan_id=u.id where t3.material_id=t1.signature limit 1),'') AS plan,
-        (select t2.cover_url from ctop_material_info t2 where t2.code=t1.signature limit 1) AS converUrl,
-        (select t2.material_name from ctop_material_info t2 where t2.code=t1.signature limit 1) AS materialName,
-        (SELECT project_name FROM ctop_project t4 WHERE t4.id = t3.project_id) AS projectName,
-        (select t2.create_time from ctop_material_info t2 where t2.code=t1.signature limit 1) as createTime,
+        SELECT
+        t1.md5 signature,
+        IFNULL(t1.toutiao_url, '') AS url,
+        t1.cover_url AS converUrl,
+        t1.clip_name AS clip,
+        t1.shot_name AS shot,
+        t1.plan_name AS plan,
+        t1.material_name AS materialName,
+        t1.project_name AS projectName,
+        t1.matertial_create_time AS createTime,
         ${filed}
         FROM
-        ctop_bytedance_video_report_daily t1
-        LEFT JOIN ctop_user_allocation t3 ON t3.account_id=t1.account_id
+        etl_report_bytedance_video t1
         WHERE
         t1.stat_datetime >= #{startDate}
         AND t1.stat_datetime &lt;= #{endDate}
@@ -27,44 +26,27 @@
                 #{item}
             </foreach>
         </if>
-        AND t1.video_url is not null
-        GROUP BY t1.signature
-        ) t
-        WHERE (t.clip LIKE '%${clip}%')
-        AND (t.shot LIKE '%${shot}%')
-        AND (t.plan LIKE '%${plan}%')
+        AND (t1.clip_name LIKE '%${clip}%')
+        AND (t1.shot_name LIKE '%${shot}%')
+        AND (t1.plan_name LIKE '%${plan}%')
+        GROUP BY t1.md5
         ORDER BY ${target} ${order}
     </select>
 
     <select id="queryVideoDetailBy" resultType="com.alibaba.fastjson.JSONObject">
         SELECT
         t1.stat_datetime as statDate,
-        t1.signature,
-        t1.video_url as url,
-        (select t2.cover_url from ctop_material_info t2 where t2.code=t1.signature limit 1) AS converUrl,
-        (select t2.material_name from ctop_material_info t2 where t2.code=t1.signature limit 1) AS materialName,
-        (
-        SELECT
-        project_name
-        FROM
-        ctop_project t4
-        WHERE
-        t4.id = t3.project_id
-        ) AS projectName,
-        (
-        SELECT
-        advertiser_name
-        FROM
-        ctop_project t4
-        WHERE
-        t4.id = t3.project_id limit 1
-        ) AS advertiserName,
-        (select t2.create_time from ctop_material_info t2 where t2.code=t1.signature limit 1) as createTime,
+        t1.md5 signature,
+        IFNULL(t1.toutiao_url, '') AS url,
+        t1.cover_url AS converUrl,
+        t1.material_name AS materialName,
+        t1.project_name AS projectName,
+        t1.advertiser_name as advertiserName,
+        t1.matertial_create_time AS createTime,
         ${filed}
         FROM
-        ctop_bytedance_video_report_daily t1
-        LEFT JOIN ctop_user_allocation t3 ON t3.account_id=t1.account_id
-        WHERE t1.signature=#{signature}
+        etl_report_bytedance_video t1
+        WHERE t1.md5=#{signature}
         AND t1.stat_datetime >= #{startDate}
         AND t1.stat_datetime &lt;= #{endDate}
         <if test="accountIds != null">
@@ -74,7 +56,7 @@
                 #{item}
             </foreach>
         </if>
-        GROUP BY t1.signature,t1.stat_datetime
+        GROUP BY t1.md5,t1.stat_datetime
         order by t1.stat_datetime desc
     </select>
 </mapper>

+ 3 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/IBytedanceVideoReportService.java

@@ -1,5 +1,6 @@
 package cn.com.ctop.toutiao.modules.report.service;
 
+import cn.com.ctop.common.module.entity.CtopOauthToken;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.PageInfo;
@@ -13,4 +14,6 @@ public interface IBytedanceVideoReportService {
     List<JSONObject> getVideoDetailBy(JSONArray accountIds, String startDate, String endDate, String filed, String signature);
 
     List<JSONObject> exportExcelReportBy(JSONArray accountIds, String startDate, String endDate, String filed, String target, String order, String clip, String shot, String plan);
+
+    void pullVideoReport(CtopOauthToken oauthToken,String startDate, String endDate,int page);
 }

+ 0 - 5
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/BytedanceReportServiceImpl.java

@@ -544,11 +544,6 @@ public class BytedanceReportServiceImpl implements IBytedanceReportService {
             record.setUpdateTime(new Date());
             recordService.updateById(record);
         }
-//        bytedanceReportMaterialDailyMapper.updateImageReportCode();
-//        bytedanceReportMaterialDailyMapper.updateImageReportProjectId();
-//        bytedanceReportMaterialDailyMapper.updateImageReportProjectName();
-//        bytedanceReportMaterialDailyMapper.updateImageReportPlaneId();
-//        bytedanceReportMaterialDailyMapper.updateImageReportPlaneName();
         log.info("头条素材报表结束 当前accountId为:{}  {}~{}" , accountId, record.getStartDate(),record.getEndDate());
     }
 

+ 66 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/BytedanceVideoReportServiceImpl.java

@@ -1,22 +1,35 @@
 package cn.com.ctop.toutiao.modules.report.service.impl;
 
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.toutiao.modules.link.entity.BaseReportBytedanceVideoDaily;
+import cn.com.ctop.toutiao.modules.link.service.IBaseReportBytedanceVideoDailyService;
 import cn.com.ctop.toutiao.modules.report.mapper.BytedanceVideoReportMapper;
 import cn.com.ctop.toutiao.modules.report.service.IBytedanceVideoReportService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
+@Slf4j
 @Service
 public class BytedanceVideoReportServiceImpl implements IBytedanceVideoReportService {
 
     @Autowired
     BytedanceVideoReportMapper bytedanceVideoReportMapper;
 
+    @Autowired
+    IBaseReportBytedanceVideoDailyService baseReportBytedanceVideoDailyService;
+
     @Override
     public PageInfo<JSONObject> getVideoReportBy(JSONArray accountIds, String startDate, String endDate, String filed, String target, String order, String clip, String shot, String plan, int pageSize, int pageNo) {
         PageHelper.startPage(pageNo,pageSize);
@@ -34,4 +47,57 @@ public class BytedanceVideoReportServiceImpl implements IBytedanceVideoReportSer
         return bytedanceVideoReportMapper.queryVideoReportBy(accountIds,startDate,endDate,filed,target,order,clip,shot,plan);
     }
 
+    @Override
+    public void pullVideoReport(CtopOauthToken oauthToken, String startDate, String endDate, int page) {
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", " application/json");
+        headers.put("Access-Token", oauthToken.getAccessToken());
+
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", oauthToken.getAccountId());
+        param.put("start_date",startDate);
+        param.put("end_date",endDate);
+        param.put("page_size", 200);
+        param.put("page", page);
+
+        JSONObject resultJson = JSONObject.parseObject(HttpUtils.httpGetRequest("https://ad.oceanengine.com/open_api/2/report/video/get/", headers, param));
+        if (Check.isNull(resultJson)) {
+            log.warn("拉取头条视频报表返回结果为空,advertiserId:{}", oauthToken.getAccountId());
+            return;
+        }
+        if(resultJson.getInteger("code")!=0){
+            log.error("拉取头条视频表异常,advertiserId:{},message:{}", oauthToken.getAccountId(),resultJson.getString("message"));
+            return;
+        }
+        JSONObject data = resultJson.getJSONObject("data");
+        if (null == data || data.size() <= 0) {
+            log.error("拉取头条视频表异常,data is null");
+            return;
+        }
+
+        JSONArray list= data.getJSONArray("list");
+        if(list.isEmpty()){
+            log.warn("拉取头条视频表,数据为空advertiserId:{}", oauthToken.getAccountId());
+            return;
+        }
+        List<BaseReportBytedanceVideoDaily> batch =new ArrayList<>();
+        list.forEach(videoReport->{
+            JSONObject videoReportJSONObject= (JSONObject)videoReport;
+            Long materialId= videoReportJSONObject.getJSONObject("dimensions").getLong("material_id");
+            JSONObject metrics= videoReportJSONObject.getJSONObject("metrics");
+            BaseReportBytedanceVideoDaily temp= JSONObject.toJavaObject(metrics,BaseReportBytedanceVideoDaily.class);
+            temp.setMaterialShow(metrics.getLong("show"));
+            temp.setAccountId(oauthToken.getAccountId());
+            temp.setMaterialId(materialId);
+            temp.setStatDatetime(startDate);
+            batch.add(temp);
+        });
+        baseReportBytedanceVideoDailyService.saveBatch(batch);
+
+        if(resultJson.getJSONObject("data").getJSONObject("page_info").getInteger("total_page")>page){
+            pullVideoReport(oauthToken, startDate, endDate, page + 1);
+        }
+    }
+
 }

+ 3 - 3
module-toutiao/src/main/resources/json_template/bytedance_video_report_mapping.json

@@ -4,11 +4,11 @@
     "comment": "消耗"
   },
   "showMaterial": {
-    "filed": "IFNULL(sum(t1.show_material),0) as showMaterial ",
+    "filed": "IFNULL(sum(t1.material_show),0) as showMaterial ",
     "comment": "展示数"
   },
   "cpm": {
-    "filed": "CASE WHEN sum(t1.cost) / sum(t1.show_material) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.show_material)) * 1000, 2 ) END AS cpm ",
+    "filed": "CASE WHEN sum(t1.cost) / sum(t1.material_show) IS NULL THEN 0 ELSE ROUND((sum(t1.cost) / sum(t1.material_show)) * 1000, 2 ) END AS cpm ",
     "comment": "平均千次展现费用"
   },
   "clickMaterial": {
@@ -16,7 +16,7 @@
     "comment": "点击数"
   },
   "ctr": {
-    "filed": "CASE WHEN sum(t1.click) / sum(t1.show_material) IS NULL THEN 0 ELSE CONCAT( ROUND((sum(t1.click) / sum(t1.show_material)) * 100,2),'%') END AS ctr ",
+    "filed": "CASE WHEN sum(t1.click) / sum(t1.material_show) IS NULL THEN 0 ELSE CONCAT( ROUND((sum(t1.click) / sum(t1.material_show)) * 100,2),'%') END AS ctr ",
     "comment": "点击率"
   },
   "cpc": {