Forráskód Böngészése

头条报表提交

zhouzeyu@c-top.com.cn 3 éve
szülő
commit
09c6a24443
21 módosított fájl, 2910 hozzáadás és 9 törlés
  1. 488 5
      jeecg-boot-report/src/main/java/cn/com/ctop/common/constant/AccountReportConstants.java
  2. 331 0
      jeecg-boot-report/src/main/java/cn/com/ctop/common/utils/ExportExcelUtils.java
  3. 930 0
      jeecg-boot-report/src/main/java/cn/com/ctop/common/utils/HttpUtils.java
  4. 24 0
      jeecg-boot-report/src/main/java/cn/com/ctop/common/utils/LinkUtils.java
  5. 214 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/controller/BytedanceAccountReportDailyDwController.java
  6. 285 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/controller/BytedanceMaterialReportDailyDwController.java
  7. 1 1
      jeecg-boot-report/src/main/java/cn/com/ctop/report/controller/KuaishouAccountReportDailyDwController.java
  8. 22 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/AccountAttributionInfoMapper.java
  9. 13 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/BytedanceAccountReportDailyDwMapper.java
  10. 13 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/BytedanceAccountReportHourlyDwMapper.java
  11. 18 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/BytedanceMaterialVideoReportDailyDwMapper.java
  12. 117 1
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/AccountAttributionInfoMapper.xml
  13. 26 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/BytedanceAccountReportDailyDwMapper.xml
  14. 24 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/BytedanceAccountReportHourlyDwMapper.xml
  15. 122 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/BytedanceMaterialVideoReportDailyDwMapper.xml
  16. 4 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/service/AccountAttributionInfoService.java
  17. 14 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/service/IBytedanceAccountReportDailyDwService.java
  18. 16 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/service/IBytedanceMaterialVideoReportDailyDwService.java
  19. 106 2
      jeecg-boot-report/src/main/java/cn/com/ctop/report/service/impl/AccountAttributionInfoServiceImpl.java
  20. 104 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/service/impl/BytedanceAccountReportDailyDwServiceImpl.java
  21. 38 0
      jeecg-boot-report/src/main/java/cn/com/ctop/report/service/impl/BytedanceMaterialVideoReportDailyDwServiceImpl.java

+ 488 - 5
jeecg-boot-report/src/main/java/cn/com/ctop/common/constant/AccountReportConstants.java

@@ -760,6 +760,159 @@ public class AccountReportConstants {
             "  }\n" +
             "}";
 
+    public static final String BYTEDANCE_VIDEO_REPORT_FILED = "{\n" +
+            "  \"materialName\": {\n" +
+            "    \"comment\": \"视频名称\"\n" +
+            "  },\n" +
+            "  \"purchaseRate\": {\n" +
+            "    \"comment\": \"首购率\"\n" +
+            "  },\n" +
+            "  \"statDate\": {\n" +
+            "    \"comment\": \"时间\"\n" +
+            "  },\n" +
+            "  \"accountId\": {\n" +
+            "    \"comment\": \"账户ID\"\n" +
+            "  },\n" +
+            "  \"authName\": {\n" +
+            "    \"comment\": \"账户昵称\"\n" +
+            "  },\n" +
+            "  \"clip\": {\n" +
+            "    \"comment\": \"剪辑\"\n" +
+            "  },\n" +
+            "  \"plan\": {\n" +
+            "    \"comment\": \"编导\"\n" +
+            "  },\n" +
+            "  \"shot\": {\n" +
+            "    \"comment\": \"拍摄\"\n" +
+            "  },\n" +
+            "  \"signature\": {\n" +
+            "    \"comment\": \"素材ID\"\n" +
+            "  },\n" +
+            "  \"designLeader\": {\n" +
+            "    \"comment\": \"设计负责人\"\n" +
+            "  },\n" +
+            "  \"createTime\": {\n" +
+            "    \"comment\": \"创建时间\"\n" +
+            "  },\n" +
+            "  \"coverUrl\": {\n" +
+            "    \"comment\": \"封面链接\"\n" +
+            "  },\n" +
+            "  \"url\": {\n" +
+            "    \"comment\": \"素材链接\"\n" +
+            "  },\n" +
+            "  \"signature\": {\n" +
+            "    \"comment\": \"素材标识\"\n" +
+            "  },\n" +
+            "  \"projectName\": {\n" +
+            "    \"comment\": \"项目名称\"\n" +
+            "  },\n" +
+            "  \"cost\": {\n" +
+            "    \"comment\": \"消耗\"\n" +
+            "  },\n" +
+            "  \"show\": {\n" +
+            "    \"comment\": \"展示数\"\n" +
+            "  },\n" +
+            "  \"click\": {\n" +
+            "    \"comment\": \"点击数\"\n" +
+            "  },\n" +
+            "  \"ctr\": {\n" +
+            "    \"comment\": \"点击率\"\n" +
+            "  },\n" +
+            "  \"avgShowCost\": {\n" +
+            "    \"comment\": \"平均千次展现费用\"\n" +
+            "  },\n" +
+            "  \"avgClickCost\": {\n" +
+            "    \"comment\": \"平均点击单价\"\n" +
+            "  },\n" +
+            "  \"convert\": {\n" +
+            "    \"comment\": \"转化数\"\n" +
+            "  },\n" +
+            "  \"convertCost\": {\n" +
+            "    \"comment\": \"转化成本\"\n" +
+            "  },\n" +
+            "  \"convertRate\": {\n" +
+            "    \"comment\": \"转化率\"\n" +
+            "  },\n" +
+            "  \"downloadStart\": {\n" +
+            "    \"comment\": \"安卓下载开始数\"\n" +
+            "  },\n" +
+            "  \"downloadStartCost\": {\n" +
+            "    \"comment\": \"安卓下载开始成本\"\n" +
+            "  },\n" +
+            "  \"downloadStartRate\": {\n" +
+            "    \"comment\": \"安卓开始下载率\"\n" +
+            "  },\n" +
+            "  \"downloadFinish\": {\n" +
+            "    \"comment\": \"安卓下载完成数\"\n" +
+            "  },\n" +
+            "  \"downloadFinishCost\": {\n" +
+            "    \"comment\": \"安卓下载完成成本\"\n" +
+            "  },\n" +
+            "  \"downloadFinishRate\": {\n" +
+            "    \"comment\": \"安卓下载完成率\"\n" +
+            "  },\n" +
+            "  \"active\": {\n" +
+            "    \"comment\": \"激活数\"\n" +
+            "  },\n" +
+            "  \"activeCost\": {\n" +
+            "    \"comment\": \"激活成本\"\n" +
+            "  },\n" +
+            "  \"activeRate\": {\n" +
+            "    \"comment\": \"激活率\"\n" +
+            "  },\n" +
+            "  \"register\": {\n" +
+            "    \"comment\": \"注册数\"\n" +
+            "  },\n" +
+            "  \"activeRegisterCost\": {\n" +
+            "    \"comment\": \"注册成本\"\n" +
+            "  },\n" +
+            "  \"activeRegisterRate\": {\n" +
+            "    \"comment\": \"注册率\"\n" +
+            "  },\n" +
+            "  \"nextDayOpen\": {\n" +
+            "    \"comment\": \"次留数\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenCost\": {\n" +
+            "    \"comment\": \"次留成本\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenRate\": {\n" +
+            "    \"comment\": \"次留率\"\n" +
+            "  },\n" +
+            "  \"payCount\": {\n" +
+            "    \"comment\": \"付费数\"\n" +
+            "  },\n" +
+            "  \"gamePayCost\": {\n" +
+            "    \"comment\": \"付费成本\"\n" +
+            "  },\n" +
+            "  \"form\": {\n" +
+            "    \"comment\": \"表单提交数\"\n" +
+            "  },\n" +
+            "  \"validPlayCost\": {\n" +
+            "    \"comment\": \"有效播放成本\"\n" +
+            "  },\n" +
+            "  \"play25FeedBreak\": {\n" +
+            "    \"comment\": \"25%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play50FeedBreak\": {\n" +
+            "    \"comment\": \"50%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play75FeedBreak\": {\n" +
+            "    \"comment\": \"75%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play100FeedBreak\": {\n" +
+            "    \"comment\": \"99%进度播放数\"\n" +
+            "  },\n" +
+            "  \"follow\": {\n" +
+            "    \"comment\": \"新增关注数\"\n" +
+            "  },\n" +
+            "  \"like\": {\n" +
+            "    \"comment\": \"点赞数数\"\n" +
+            "  },\n" +
+            "  \"share\": {\n" +
+            "    \"comment\": \"分享数\"\n" +
+            "  },\n" +
+            "}";
+
     public static final String BYTEDANCE_VIDEO_REPORT_MAPPING_JSON = "{\n" +
             "  \"cost\": {\n" +
             "    \"filed\": \"IFNULL(sum(t1.cost),0) as cost \",\n" +
@@ -914,23 +1067,353 @@ public class AccountReportConstants {
             "    \"comment\": \"展示数\"\n" +
             "  }\n" +
             "}";
-    public static Map<String, Map<String, Object>> getDictMapBy(){
+
+    public static final String BYTEDANCE_VIDEO_REPORT_FILED_MAPPING_JSON = "{\n" +
+            "  \"signature\": {\n" +
+            "    \"filed\": \"IFNULL(signature,'-') as signature \",\n" +
+            "    \"comment\": \"素材标识\"\n" +
+            "  },\n" +
+            "  \"projectName\": {\n" +
+            "    \"filed\": \"project_name as projectName \",\n" +
+            "    \"comment\": \"项目名称\"\n" +
+            "  },\n" +
+            "  \"purchaseRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(`convert`) != 0 THEN CONCAT(CAST(ROUND((sum(in_app_pay) / sum(`convert`)) * 100,2) AS CHAR) ,'%') ELSE '0%' end  as purchaseRate \",\n" +
+            "    \"comment\": \"首购率\"\n" +
+            "  },\n" +
+            "  \"cost\": {\n" +
+            "    \"filed\": \"IFNULL(ROUND(sum(cost),2),0) as cost \",\n" +
+            "    \"comment\": \"消耗\"\n" +
+            "  },\n" +
+            "  \"show\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`show`),0) as `show` \",\n" +
+            "    \"comment\": \"展示数\"\n" +
+            "  },\n" +
+            "  \"click\": {\n" +
+            "    \"filed\": \"IFNULL(sum(click),0) as click \",\n" +
+            "    \"comment\": \"点击数\"\n" +
+            "  },\n" +
+            "  \"ctr\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(`show`) != 0 THEN CONCAT(CAST(ROUND((sum(click) / sum(`show`)) * 100,2) AS CHAR) ,'%') ELSE '0%' end  as ctr\",\n" +
+            "    \"comment\": \"点击率\"\n" +
+            "  },\n" +
+            "  \"avgShowCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(`show`) IS NULL THEN 0 ELSE ROUND(sum(cost)/sum(`show`)*1000,2) END as avgShowCost\",\n" +
+            "    \"comment\": \"平均千次展现费用\"\n" +
+            "  },\n" +
+            "  \"avgClickCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(click) / sum(cost) IS NULL THEN 0 ELSE ROUND((sum(cost) / sum(click)), 2) END  as avgClickCost\",\n" +
+            "    \"comment\": \"平均点击单价\"\n" +
+            "  },\n" +
+            "  \"convert\": {\n" +
+            "    \"filed\": \"IFNULL(SUM(`convert`),0) as `convert`\",\n" +
+            "    \"comment\": \"转化数\"\n" +
+            "  },\n" +
+            "  \"convertCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(`convert`) IS NULL THEN 0 ELSE ROUND((sum(cost) / sum(`convert`)), 2 ) END as convertCost \",\n" +
+            "    \"comment\": \"转化成本\"\n" +
+            "  },\n" +
+            "  \"convertRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(click)!= 0 THEN concat(CAST(round(sum(`convert`) / sum(click)*100,2) AS CHAR) ,'%') ELSE '0%' end as convertRate\",\n" +
+            "    \"comment\": \"转化率\"\n" +
+            "  },\n" +
+            "  \"downloadStart\": {\n" +
+            "    \"filed\": \"IFNULL(SUM(download_start),0) as downloadStart\",\n" +
+            "    \"comment\": \"安卓下载开始数\"\n" +
+            "  },\n" +
+            "  \"downloadStartCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / (download_start) IS NULL THEN 0 ELSE ROUND(sum(cost) / sum(download_start),2) end as downloadStartCost\",\n" +
+            "    \"comment\": \"安卓下载开始成本\"\n" +
+            "  },\n" +
+            "  \"downloadStartRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(download_start) != 0 THEN concat(CAST(round(sum(download_start) / sum(click)*100,2) AS CHAR) ,'%') ELSE '0%' end  as  downloadStartRate\",\n" +
+            "    \"comment\": \"安卓开始下载率\"\n" +
+            "  },\n" +
+            "  \"downloadFinish\": {\n" +
+            "    \"filed\": \"IFNULL(sum(download_finish),0) as downloadFinish \",\n" +
+            "    \"comment\": \"安卓下载完成数\"\n" +
+            "  },\n" +
+            "  \"downloadFinishCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(download_finish) IS NULL THEN 0 ELSE  sum(cost) / sum(download_finish) end as downloadFinishCost\",\n" +
+            "    \"comment\": \"安卓下载完成成本\"\n" +
+            "  },\n" +
+            "  \"downloadFinishRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(download_start) != 0 THEN concat(CAST(round(sum(download_finish) / sum(download_start)*100,2) AS CHAR) ,'%') ELSE '0%' end  as  downloadFinishRate \",\n" +
+            "    \"comment\": \"安卓下载完成率\"\n" +
+            "  },\n" +
+            "  \"active\": {\n" +
+            "    \"filed\": \"IFNULL(sum(active),0) as active \",\n" +
+            "    \"comment\": \"激活数\"\n" +
+            "  },\n" +
+            "  \"activeCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(active) IS NULL THEN 0 ELSE ROUND(sum(cost) / sum(active),2) end as activeCost\",\n" +
+            "    \"comment\": \"激活成本\"\n" +
+            "  },\n" +
+            "  \"activeRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(click) != 0 THEN concat(CAST(round(sum(active) / sum(click)*100,2) AS CHAR) ,'%') ELSE '0%' end    as  activeRate\",\n" +
+            "    \"comment\": \"激活率\"\n" +
+            "  },\n" +
+            "  \"register\": {\n" +
+            "    \"filed\": \"IFNULL(sum(register),0) as register \",\n" +
+            "    \"comment\": \"注册数\"\n" +
+            "  },\n" +
+            "  \"activeRegisterCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(register) IS NULL THEN 0 ELSE round(sum(cost)/sum(register),2) end  as activeRegisterCost\",\n" +
+            "    \"comment\": \"注册成本\"\n" +
+            "  },\n" +
+            "  \"activeRegisterRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(active) != 0 THEN concat(CAST(round(sum(register) / sum(active)*100,2) AS CHAR) ,'%') ELSE '0%' end   as  activeRegisterRate\",\n" +
+            "    \"comment\": \"注册率\"\n" +
+            "  },\n" +
+            "  \"nextDayOpen\": {\n" +
+            "    \"filed\": \"IFNULL(sum(next_day_open),0) as nextDayOpen \",\n" +
+            "    \"comment\": \"次留数\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(next_day_open) IS NULL THEN 0 ELSE round(sum(cost)/sum(next_day_open),2) end as nextDayOpenCost\",\n" +
+            "    \"comment\": \"次留成本\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(active) != 0 THEN concat(CAST(round(sum(next_day_open) / sum(active)*100,2) AS CHAR) ,'%') ELSE '0%' end   as  nextDayOpenRate\",\n" +
+            "    \"comment\": \"次留率\"\n" +
+            "  },\n" +
+            "  \"payCount\": {\n" +
+            "    \"filed\": \"IFNULL(sum(game_pay_count),0) as gamePayCount \",\n" +
+            "    \"comment\": \"付费数\"\n" +
+            "  },\n" +
+            "  \"gamePayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(game_pay_count) IS NULL THEN 0 ELSE round(sum(cost)/sum(game_pay_count),2) end as gamePayCost\",\n" +
+            "    \"comment\": \"付费成本\"\n" +
+            "  },\n" +
+            "  \"form\": {\n" +
+            "    \"filed\": \"IFNULL(sum(form),0) as form \",\n" +
+            "    \"comment\": \"表单提交数\"\n" +
+            "  },\n" +
+            "  \"validPlayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(valid_play) IS NULL THEN 0 ELSE round(sum(cost)/sum(valid_play),2) end   as validPlayCost \",\n" +
+            "    \"comment\": \"有效播放成本\"\n" +
+            "  },\n" +
+            "  \"play25FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_25_feed_break),0) as play25FeedBreak \",\n" +
+            "    \"comment\": \"25%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play50FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_50_feed_break),0) as play50FeedBreak \",\n" +
+            "    \"comment\": \"50%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play75FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_75_feed_break),0) as play75FeedBreak \",\n" +
+            "    \"comment\": \"75%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play100FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_100_feed_break),0) as play100FeedBreak \",\n" +
+            "    \"comment\": \"99%进度播放数\"\n" +
+            "  },\n" +
+            "  \"follow\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`follow`),0) as `follow` \",\n" +
+            "    \"comment\": \"新增关注数\"\n" +
+            "  },\n" +
+            "  \"like\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`like`),0) as `like` \",\n" +
+            "    \"comment\": \"点赞数数\"\n" +
+            "  },\n" +
+            "  \"share\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`share`),0) as `share` \",\n" +
+            "    \"comment\": \"分享数\"\n" +
+            "  },\n" +
+            "}";
+
+
+    public static final String BYTEDANCE_ACCOUNT_REPORT_FILED_MAPPING_JSON = "{\n" +
+            "  \"projectName\": {\n" +
+            "    \"filed\": \"project_name as projectName \",\n" +
+            "    \"comment\": \"项目名称\"\n" +
+            "  },\n" +
+            "  \"purchaseRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(`convert`) != 0 THEN CONCAT(CAST(ROUND((sum(in_app_pay) / sum(`convert`)) * 100,2) AS CHAR) ,'%') ELSE '0%' end  as purchaseRate \",\n" +
+            "    \"comment\": \"首购率\"\n" +
+            "  },\n" +
+            "  \"cost\": {\n" +
+            "    \"filed\": \"ROUND(IFNULL(sum(cost),0),2) as cost \",\n" +
+            "    \"comment\": \"消耗\"\n" +
+            "  },\n" +
+            "  \"show\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`show`),0) as `show` \",\n" +
+            "    \"comment\": \"展示数\"\n" +
+            "  },\n" +
+            "  \"click\": {\n" +
+            "    \"filed\": \"IFNULL(sum(click),0) as click \",\n" +
+            "    \"comment\": \"点击数\"\n" +
+            "  },\n" +
+            "  \"ctr\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(`show`) != 0 THEN CONCAT(CAST(ROUND((sum(click) / sum(`show`)) * 100,2) AS CHAR) ,'%') ELSE '0%' end  as ctr\",\n" +
+            "    \"comment\": \"点击率\"\n" +
+            "  },\n" +
+            "  \"avgShowCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(`show`) IS NULL THEN 0 ELSE ROUND(sum(cost)/sum(`show`)*1000,2) END as avgShowCost\",\n" +
+            "    \"comment\": \"平均千次展现费用\"\n" +
+            "  },\n" +
+            "  \"avgClickCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(click) / sum(cost) IS NULL THEN 0 ELSE ROUND((sum(cost) / sum(click)), 2) END as avgClickCost\",\n" +
+            "    \"comment\": \"平均点击单价\"\n" +
+            "  },\n" +
+            "  \"convert\": {\n" +
+            "    \"filed\": \"IFNULL(SUM(`convert`),0) as `convert`\",\n" +
+            "    \"comment\": \"转化数\"\n" +
+            "  },\n" +
+            "  \"convertCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(`convert`) IS NULL THEN 0 ELSE ROUND((sum(cost) / sum(`convert`)), 2 ) END as convertCost \",\n" +
+            "    \"comment\": \"转化成本\"\n" +
+            "  },\n" +
+            "  \"convertRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(click)!= 0 THEN concat(CAST(round(sum(`convert`) / sum(click)*100,2) AS CHAR) ,'%') ELSE '0%' end as convertRate\",\n" +
+            "    \"comment\": \"转化率\"\n" +
+            "  },\n" +
+            "  \"downloadStart\": {\n" +
+            "    \"filed\": \"IFNULL(SUM(download_start),0) as downloadStart\",\n" +
+            "    \"comment\": \"安卓下载开始数\"\n" +
+            "  },\n" +
+            "  \"downloadStartCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / (download_start) IS NULL THEN 0 ELSE ROUND(sum(cost) / sum(download_start),2) end as downloadStartCost\",\n" +
+            "    \"comment\": \"安卓下载开始成本\"\n" +
+            "  },\n" +
+            "  \"downloadStartRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(download_start) != 0 THEN concat(CAST(round(sum(download_start) / sum(click)*100,2) AS CHAR) ,'%') ELSE '0%' end  as  downloadStartRate\",\n" +
+            "    \"comment\": \"安卓开始下载率\"\n" +
+            "  },\n" +
+            "  \"downloadFinish\": {\n" +
+            "    \"filed\": \"IFNULL(sum(download_finish),0) as downloadFinish \",\n" +
+            "    \"comment\": \"安卓下载完成数\"\n" +
+            "  },\n" +
+            "  \"downloadFinishCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(download_finish) IS NULL THEN 0 ELSE  ROUND(sum(cost) / sum(download_finish),2) end as downloadFinishCost\",\n" +
+            "    \"comment\": \"安卓下载完成成本\"\n" +
+            "  },\n" +
+            "  \"downloadFinishRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(download_start) != 0 THEN concat(CAST(round(sum(download_finish) / sum(download_start)*100,2) AS CHAR) ,'%') ELSE '0%' end   as  downloadFinishRate \",\n" +
+            "    \"comment\": \"安卓下载完成率\"\n" +
+            "  },\n" +
+            "  \"active\": {\n" +
+            "    \"filed\": \"IFNULL(sum(active),0) as active \",\n" +
+            "    \"comment\": \"激活数\"\n" +
+            "  },\n" +
+            "  \"activeCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(active) IS NULL THEN 0 ELSE ROUND(sum(cost) / sum(active),2) end as activeCost\",\n" +
+            "    \"comment\": \"激活成本\"\n" +
+            "  },\n" +
+            "  \"activeRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(click) != 0 THEN concat(CAST(round(sum(active) / sum(click)*100,2) AS CHAR) ,'%') ELSE '0%' end    as  activeRate\",\n" +
+            "    \"comment\": \"激活率\"\n" +
+            "  },\n" +
+            "  \"register\": {\n" +
+            "    \"filed\": \"IFNULL(sum(register),0) as register \",\n" +
+            "    \"comment\": \"注册数\"\n" +
+            "  },\n" +
+            "  \"activeRegisterCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(register) IS NULL THEN 0 ELSE round(sum(cost)/sum(register),2) end as activeRegisterCost\",\n" +
+            "    \"comment\": \"注册成本\"\n" +
+            "  },\n" +
+            "  \"activeRegisterRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(active) != 0 THEN concat(CAST(round(sum(register) / sum(active)*100,2) AS CHAR) ,'%') ELSE '0%' end   as  activeRegisterRate\",\n" +
+            "    \"comment\": \"注册率\"\n" +
+            "  },\n" +
+            "  \"nextDayOpen\": {\n" +
+            "    \"filed\": \"IFNULL(sum(next_day_open),0) as nextDayOpen \",\n" +
+            "    \"comment\": \"次留数\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(next_day_open) IS NULL THEN 0 ELSE round(sum(cost)/sum(next_day_open),2) end as nextDayOpenCost\",\n" +
+            "    \"comment\": \"次留成本\"\n" +
+            "  },\n" +
+            "  \"nextDayOpenRate\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(active) != 0 THEN concat(CAST(round(sum(next_day_open) / sum(active)*100,2) AS CHAR) ,'%') ELSE '0%' end   as  nextDayOpenRate\",\n" +
+            "    \"comment\": \"次留率\"\n" +
+            "  },\n" +
+            "  \"payCount\": {\n" +
+            "    \"filed\": \"IFNULL(sum(game_pay_count),0) as gamePayCount \",\n" +
+            "    \"comment\": \"付费数\"\n" +
+            "  },\n" +
+            "  \"gamePayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(game_pay_count) IS NULL THEN 0 ELSE round(sum(cost)/sum(game_pay_count),2) end as gamePayCost\",\n" +
+            "    \"comment\": \"付费成本\"\n" +
+            "  },\n" +
+            "  \"form\": {\n" +
+            "    \"filed\": \"IFNULL(sum(form),0) as form \",\n" +
+            "    \"comment\": \"表单提交数\"\n" +
+            "  },\n" +
+            "  \"validPlayCost\": {\n" +
+            "    \"filed\": \"CASE WHEN sum(cost) / sum(valid_play) IS NULL THEN 0 ELSE round(sum(cost)/sum(valid_play),2) end as validPlayCost \",\n" +
+            "    \"comment\": \"有效播放成本\"\n" +
+            "  },\n" +
+            "  \"play25FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_25_feed_break),0) as play25FeedBreak \",\n" +
+            "    \"comment\": \"25%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play50FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_50_feed_break),0) as play50FeedBreak \",\n" +
+            "    \"comment\": \"50%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play75FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_75_feed_break),0) as play75FeedBreak \",\n" +
+            "    \"comment\": \"75%进度播放数\"\n" +
+            "  },\n" +
+            "  \"play100FeedBreak\": {\n" +
+            "    \"filed\": \"IFNULL(sum(play_100_feed_break),0) as play100FeedBreak \",\n" +
+            "    \"comment\": \"99%进度播放数\"\n" +
+            "  },\n" +
+            "  \"follow\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`follow`),0) as `follow` \",\n" +
+            "    \"comment\": \"新增关注数\"\n" +
+            "  },\n" +
+            "  \"like\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`like`),0) as `like` \",\n" +
+            "    \"comment\": \"点赞数数\"\n" +
+            "  },\n" +
+            "  \"share\": {\n" +
+            "    \"filed\": \"IFNULL(sum(`share`),0) as `share` \",\n" +
+            "    \"comment\": \"分享数\"\n" +
+            "  },\n" +
+            "}";
+
+    public static Map<String, Map<String, Object>> getDictMapBy() {
         JSONObject jsonBy = JSON.parseObject(BYTEDANCE_FILED_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(jsonBy);
     }
-    public static Map<String, Map<String, Object>> getDicMapKs(){
+
+    public static Map<String, Map<String, Object>> getDicMapKs() {
         Object jsonKs = JSON.parseObject(KUAISHOU_FILED_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(jsonKs);
     }
-    public static Map<String, Map<String, Object>> getDicMapByVideo(){
+
+    public static Map<String, Map<String, Object>> getDicMapByVideo() {
         Object jsonByVideo = JSON.parseObject(BYTEDANCE_VIDEO_REPORT_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(jsonByVideo);
     }
-    public static Map<String, Map<String, Object>> getKuaishouVideoReportMap(){
+
+    public static Map<String, Map<String, Object>> getKuaishouVideoReportMap() {
         Object kuaiShouVideoJson = JSON.parseObject(KUAISHOU_VIDEO_REPORT_FILED_MAPPING_JSON);
         return JsonResourceUtil.jsonToMap(kuaiShouVideoJson);
     }
-    public static Map<String, Map<String, Object>> getKuaishouVideoReportDict(){
+
+    public static Map<String, Map<String, Object>> getBytedanceVideoReportMap() {
+        Object bytedanceVideoJson = JSON.parseObject(BYTEDANCE_VIDEO_REPORT_FILED_MAPPING_JSON);
+        return JsonResourceUtil.jsonToMap(bytedanceVideoJson);
+
+    }
+
+    public static Map<String, Map<String, Object>> getBytedanceVideoFiled() {
+        Object bytedanceVideoJson = JSON.parseObject(BYTEDANCE_VIDEO_REPORT_FILED);
+        return JsonResourceUtil.jsonToMap(bytedanceVideoJson);
+
+    }
+
+
+    public static Map<String, Map<String, Object>> getBytedanceAccountReportMap() {
+        Object bytedanceVideoJson = JSON.parseObject(BYTEDANCE_ACCOUNT_REPORT_FILED_MAPPING_JSON);
+        return JsonResourceUtil.jsonToMap(bytedanceVideoJson);
+    }
+
+    public static Map<String, Map<String, Object>> getKuaishouVideoReportDict() {
         Object kuaiShouVideoDictJson = JSON.parseObject(KUAISHOU_VIDEO_REPORT_FILED_DICT_JSON);
         return JsonResourceUtil.jsonToMap(kuaiShouVideoDictJson);
     }

+ 331 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/common/utils/ExportExcelUtils.java

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

+ 930 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/common/utils/HttpUtils.java

@@ -0,0 +1,930 @@
+package cn.com.ctop.common.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.*;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.cookie.Cookie;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.cookie.BasicClientCookie;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.SSLContext;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.*;
+
+/**
+ * @author 宋英豪
+ */
+@Slf4j
+public class HttpUtils {
+
+    //发送响应流方法
+    public static void setResponseHeader(HttpServletResponse response, String fileName) {
+        try {
+            fileName = new String(fileName.getBytes(), StandardCharsets.UTF_8);
+            //response.setContentType("application/octet-stream;charset=ISO8859-1");
+            response.setContentType("application/vnd.ms-excel;charset=gb2312");
+
+            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+            response.addHeader("Pargam", "no-cache");
+            response.addHeader("Cache-Control", "no-cache");
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+
+    public static JSONObject bytedanceGetRequest(String accessToken, String url, JSONObject params) {
+        // 构造请求
+        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
+            @Override
+            public String getMethod() {
+                return "GET";
+            }
+        };
+        httpEntity.setHeader("Access-Token", accessToken);
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setURI(URI.create(url));
+            httpEntity.setEntity(new StringEntity(params.toJSONString(), ContentType.APPLICATION_JSON));
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(12000).setConnectTimeout(12000).build();
+            httpEntity.setConfig(requestConfig);
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder result = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (client != null) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    public static JSONObject bytedancePostRequest(String accessToken, String url, JSONObject params) {
+        // 构造请求
+        HttpPost httpEntity = new HttpPost(url);
+        httpEntity.setHeader("Access-Token", accessToken);
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setEntity(new StringEntity(params.toJSONString(), ContentType.APPLICATION_JSON));
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(12000).setConnectTimeout(12000).build();
+            httpEntity.setConfig(requestConfig);
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder result = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (client != null) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    public static CookieStore COOKIESTORE = new BasicCookieStore();
+    /**
+     * setProxy(new HttpHost("106.125.239.179", 4245))
+     */
+    public static Map<String, Map<String, String>> fontsMap = new HashMap<>();
+    public static String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36";
+
+    public static CloseableHttpClient createSslClientDefault() {
+        try {
+            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+                //信任所有证书
+                @Override
+                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                    return true;
+                }
+            }).build();
+            RequestConfig globalConfig = RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000).setCookieSpec(CookieSpecs.STANDARD).build();
+            SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext);
+            return HttpClients.custom().setDefaultCookieStore(COOKIESTORE).setDefaultRequestConfig(globalConfig).setConnectionReuseStrategy((response, context) -> false).setSSLSocketFactory(sslFactory).build();
+        } catch (Exception e) {
+            log.error("处理Https证书异常", e);
+        }
+        return HttpClients.createDefault();
+    }
+
+    public static String httpPostFormRequest(String url, Map<String, Object> param, Map<String, String> headers) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            if (headers != null) {
+                for (String key : headers.keySet()) {
+                    httppost.setHeader(key, headers.get(key));
+                }
+            }
+            List<NameValuePair> paramList = new ArrayList<NameValuePair>();
+            if (param != null) {
+                for (String key : param.keySet()) {
+                    BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, String.valueOf(param.get(key)));
+                    paramList.add(basicNameValuePair);
+                }
+                // 第二步:我们发现Entity是一个接口,所以只能找实现类,发现实现类又需要一个集合,集合的泛型是NameValuePair类型
+                UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramList);
+                // 第一步:通过setEntity 将我们的entity对象传递过去
+                httppost.setEntity(formEntity);
+            }
+
+            HttpEntity respentity;
+
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpPostFormRequest(newUrl, param, headers);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static String httpPostParamRequest(String url, Map<String, Object> param, Map<String, String> headers) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            if (headers != null) {
+                for (String key : headers.keySet()) {
+                    httppost.setHeader(key, headers.get(key));
+                }
+            }
+            List<NameValuePair> paramList = new ArrayList<NameValuePair>();
+            for (String key : param.keySet()) {
+                BasicNameValuePair basicNameValuePair = new BasicNameValuePair(key, String.valueOf(param.get(key)));
+                paramList.add(basicNameValuePair);
+            }
+
+            // 第二步:我们发现Entity是一个接口,所以只能找实现类,发现实现类又需要一个集合,集合的泛型是NameValuePair类型
+            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramList);
+            // 第一步:通过setEntity 将我们的entity对象传递过去
+            httppost.setEntity(formEntity);
+            httppost.setEntity(new StringEntity(new Gson().toJson(param), Charset.forName("UTF-8")));
+            HttpEntity respentity;
+
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpPostParamRequest(newUrl, param, headers);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static String httpPostRequest(String url, Map<String, Object> param, Map<String, String> headers) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            httppost.addHeader("Content-Type", "application/json");
+            if (headers != null && headers.size() > 0) {
+                for (String key : headers.keySet()) {
+                    httppost.setHeader(key, headers.get(key));
+                }
+            }
+            if (param != null && param.size() > 0) {
+                httppost.setEntity(new StringEntity(new Gson().toJson(param), Charset.forName("UTF-8")));
+            }
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(300 * 1000).setConnectTimeout(300 * 1000).build();
+            httppost.setConfig(requestConfig);
+            HttpEntity respentity;
+
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpPostRequest(newUrl, param, headers);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static String httpPostNoParamRequest(String url) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            httppost.addHeader("Content-Type", "application/json");
+            HttpEntity respentity;
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpPostNoParamRequest(newUrl);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+
+    public static String httpPostRequestTest(String url, String body, Map<String, String> headers) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            httppost.addHeader("Content-Type", "application/json");
+            if (!Check.isNull(headers)) {
+                for (String key : headers.keySet()) {
+                    httppost.setHeader(key, headers.get(key));
+                }
+            }
+
+            httppost.setEntity(new StringEntity(body, Charset.forName("UTF-8")));
+            HttpEntity respentity;
+
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpPostRequestTest(newUrl, body, headers);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+
+    public static String kuaiShouhttpPostRequest(String url, String body, Map<String, String> headers) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
+            httppost.setConfig(requestConfig);
+            if (!Check.isNullMap(headers)) {
+                for (String key : headers.keySet()) {
+                    httppost.setHeader(key, headers.get(key));
+                }
+            }
+
+            httppost.setHeader("User-Agent", USER_AGENT);
+            if (!Check.isNull(body)) {
+                httppost.setEntity(new StringEntity(body, Charset.forName("UTF-8")));
+            }
+            HttpEntity respentity;
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+
+    public static String httpPostRequest(String url, JSONObject params, Map<String, String> headers) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            httppost.addHeader("Content-Type", "application/json");
+            for (String key : headers.keySet()) {
+                httppost.setHeader(key, headers.get(key));
+            }
+            httppost.setEntity(new StringEntity(params.toJSONString(), Charset.forName("UTF-8")));
+            HttpEntity respentity;
+
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpPostRequest(newUrl, params, headers);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                respentity = response.getEntity();
+                strReturn = EntityUtils.toString(respentity);
+                return strReturn;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static String postKuaishouVideoUrl(String url, String uid, String photoId) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        String paramBody = "{\"operationName\":\"FeedQuery\",\"variables\":{\"principalId\":\"" + uid + "\",\"photoId\":\"" + photoId + "\"},\"query\":\"query FeedQuery($principalId: String, $photoId: String) {\\n  feedById(principalId: $principalId, photoId: $photoId) {\\n    currentWork {\\n                 timestamp\\n           __typename\\n    }\\n       __typename\\n  }\\n}\\n\"}";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            httppost.addHeader("Content-Type", "application/json");
+//            for (String key : headers.keySet()) {
+//                httppost.setHeader(key, headers.get(key));
+//            }
+            httppost.setEntity(new StringEntity(paramBody, Charset.forName("UTF-8")));
+            HttpEntity respentity;
+
+            HttpResponse response = httpClient.execute(httppost);
+            int statusCode = response.getStatusLine().getStatusCode();
+
+            respentity = response.getEntity();
+            strReturn = EntityUtils.toString(respentity);
+            return strReturn;
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static String getKuaishouShareUrl(String url) {
+        HttpClient httpClient = HttpClientBuilder.create().build();
+        HttpResponse response = null;
+        HttpGet httpGet = new HttpGet(url);
+        httpGet.setConfig(RequestConfig.custom().setRedirectsEnabled(false).build());
+        String result = null;
+        try {
+            httpGet.setHeader("User-Agent", USER_AGENT);
+            httpGet.setHeader("Accept-Encoding", "gzip, deflate, br");
+            httpGet.setHeader("Connection", "keep-alive");
+            httpGet.setHeader("Host", "yongzhou.s.gifshow.com");
+            httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
+            httpGet.setHeader("Upgrade-Insecure-Requests", "1");
+            httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9");
+            response = httpClient.execute(httpGet);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return newUrl;
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    public static String httpGetRequest(String url) {
+        HttpClient httpClient = createSslClientDefault();
+        HttpResponse response = null;
+        HttpGet httpGet = new HttpGet(url);
+        String result = null;
+        try {
+            httpGet.setHeader("User-Agent", USER_AGENT);
+            response = httpClient.execute(httpGet);
+            int statusCode = response.getStatusLine().getStatusCode();
+            if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
+                String newUrl = response.getFirstHeader("Location").getValue();
+                return httpGetRequest(newUrl);
+            } else if (statusCode == HttpStatus.SC_OK) {
+                BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                String line = null;
+                StringBuilder builder = new StringBuilder();
+                while ((line = reader.readLine()) != null) {
+                    builder.append(line);
+                }
+                result = builder.toString();
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    public static String httpRequest(String url, String strParams) throws Exception {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+
+            HttpPost httppost = new HttpPost(url);
+            httppost.addHeader("Content-Type", "application/json");
+            httppost.setEntity(new StringEntity(strParams, Charset.forName("UTF-8")));
+            HttpEntity respentity;
+            HttpResponse response = httpClient.execute(httppost);
+            respentity = response.getEntity();
+            strReturn = EntityUtils.toString(respentity);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static String httpRequest(String url, CookieStore cookies, Map<String, String> parameterMap) throws Exception {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("Content-Type", "application/json");
+            UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(
+                    getParam(parameterMap), "UTF-8");
+            httppost.setEntity(postEntity);
+            HttpEntity respentity;
+            HttpResponse response = httpClient.execute(httppost);
+            respentity = response.getEntity();
+            strReturn = EntityUtils.toString(respentity);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+    public static List<NameValuePair> getParam(Map parameterMap) {
+        List<NameValuePair> param = new ArrayList<>();
+        Iterator it = parameterMap.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry parmEntry = (Map.Entry) it.next();
+            param.add(new BasicNameValuePair((String) parmEntry.getKey(),
+                    (String) parmEntry.getValue()));
+        }
+        return param;
+    }
+
+    public static HttpClient getHttpclient() {
+        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(180000).setConnectTimeout(30000)
+                .setConnectionRequestTimeout(30000).setStaleConnectionCheckEnabled(true).build();
+        CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
+        return httpclient;
+    }
+
+    public static String callingGraph(String url, String json) {
+        HttpClient httpClient = createSslClientDefault();
+        HttpResponse response = null;
+        HttpPost httpPost = new HttpPost(url);
+        List<Cookie> list = COOKIESTORE.getCookies();
+        httpPost.setHeader("Content-Type", "application/json");
+        String result = null;
+
+        try {
+            StringEntity entity = new StringEntity(json, "utf-8");
+            httpPost.setHeader("User-Agent", USER_AGENT);
+            httpPost.setEntity(entity);
+            response = httpClient.execute(httpPost);
+            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+            String line = null;
+            StringBuilder builder = new StringBuilder();
+            while ((line = reader.readLine()) != null) {
+                builder.append(line);
+            }
+            result = builder.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    public static Map<String, Integer> KUAISHOUNUMBERMAP;
+
+    public static Integer getKuaishouNumber(String key) {
+        if (KUAISHOUNUMBERMAP == null) {
+            KUAISHOUNUMBERMAP = new HashMap<>();
+//            kuaishouNumberMap.put("32.0#-6.0#526.0#729.0",0);//735
+//            kuaishouNumberMap.put("98.0#13.0#363.0#726.0",1);//713
+//            kuaishouNumberMap.put("32.0#13.0#527.0#732.0",2);//719
+//            kuaishouNumberMap.put("25.0#-6.0#525.0#730.0",3);//736
+//            kuaishouNumberMap.put("26.0#13.0#536.0#731.0",4);//718
+//            kuaishouNumberMap.put("33.0#-5.0#526.0#717.0",5);//722
+//            kuaishouNumberMap.put("39.0#-5.0#530.0#732.0",6);//737
+//            kuaishouNumberMap.put("38.0#13.0#536.0#717.0",7);//704
+//            kuaishouNumberMap.put("33.0#-7.0#525.0#731.0",8);//738
+//            kuaishouNumberMap.put("37.0#-7.0#521.0#730.0",9);//737
+            KUAISHOUNUMBERMAP.put("494.0#735.0", 0);
+            KUAISHOUNUMBERMAP.put("265.0#713.0", 1);
+            KUAISHOUNUMBERMAP.put("495.0#719.0", 2);
+            KUAISHOUNUMBERMAP.put("500.0#736.0", 3);
+            KUAISHOUNUMBERMAP.put("510.0#718.0", 4);
+            KUAISHOUNUMBERMAP.put("493.0#722.0", 5);
+            KUAISHOUNUMBERMAP.put("491.0#737.0", 6);
+            KUAISHOUNUMBERMAP.put("498.0#704.0", 7);
+            KUAISHOUNUMBERMAP.put("492.0#738.0", 8);
+            KUAISHOUNUMBERMAP.put("484.0#737.0", 9);
+        }
+        return KUAISHOUNUMBERMAP.get(key);
+    }
+
+
+    public static String mapParamsSortToStringBySeperator(TreeMap<String, Object> treeMap, String seperator) {
+        String result = "";
+        if (null != treeMap && !treeMap.isEmpty()) {
+            for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
+                String key = entry.getKey();
+                String value = entry.getValue().toString();
+                result += (key + "=" + value + seperator);
+            }
+            result = result.substring(0, result.length() - seperator.length());
+        }
+        return result;
+    }
+
+    public static String httpGetRequest(String url, Map<String, String> headers, TreeMap<String, Object> params) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            String uri = url + "?" + mapParamsSortToStringBySeperator(params, "&");
+            HttpGet httpGet = new HttpGet(uri);
+            if (headers != null) {
+                Iterator<String> keyIter = headers.keySet().iterator();
+                while (keyIter.hasNext()) {
+                    String curKey = keyIter.next();
+                    if (curKey != null && headers.get(curKey) != null) {
+                        httpGet.addHeader(curKey, headers.get(curKey));
+                    }
+                }
+            }
+            HttpEntity respentity;
+            HttpResponse response = httpClient.execute(httpGet);
+            respentity = response.getEntity();
+            strReturn = EntityUtils.toString(respentity);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+
+    public static String httpGet(String url, Map<String, Object> paramsMap, Map<String, String> headers) {
+        String result = null;
+        try {
+            //创建参数列表
+            HttpClient httpclient = getHttpclient();
+            StringBuilder postBody = null;
+            if (!Check.isNull(paramsMap)) {
+                postBody = new StringBuilder();
+                for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
+                    if (entry.getValue() == null) {
+                        continue;
+                    }
+                    postBody.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue().toString(),
+                            "utf-8")).append("&");
+                }
+                if (!paramsMap.isEmpty()) {
+                    postBody.deleteCharAt(postBody.length() - 1);
+                }
+            }
+            String urlStr;
+            if (!Check.isNull(postBody)) {
+                urlStr = url + "?" + postBody;
+            } else {
+                urlStr = url;
+            }
+            HttpGet httpget = new HttpGet(urlStr);
+//            httpget.setHeader("User-Agent", USER_AGENT);
+            if (!Check.isNullMap(headers)) {
+                for (String key : headers.keySet()) {
+                    httpget.setHeader(key, headers.get(key));
+                }
+            }
+            HttpEntity respEntity;
+            HttpResponse response = httpclient.execute(httpget);
+            respEntity = response.getEntity();
+            Header[] responseHeaders = response.getHeaders("Set-Cookie");
+            if (responseHeaders != null) {
+
+                for (Header header : responseHeaders) {
+                    String[] ckArray = header.getValue().split(";");
+                    BasicClientCookie ck = new BasicClientCookie(ckArray[0].split("=")[0], ckArray[0].split("=")[1]);
+                    ck.setPath(ckArray[1].split("=")[1]);
+                    ck.setDomain(ckArray[2].split("=")[1]);
+                    HttpUtils.COOKIESTORE.addCookie(ck);
+                }
+            }
+            result = EntityUtils.toString(respEntity);
+        } catch (Exception e) {
+            log.error("http get请求异常");
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+
+    public static JSONObject kuaiShouHttpGetRequest(String accessToken, String url, JSONObject params) {
+        // 构造请求
+        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
+            @Override
+            public String getMethod() {
+                return "GET";
+            }
+        };
+        httpEntity.setHeader("Access-Token", accessToken);
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setURI(URI.create(url));
+            httpEntity.setEntity(new StringEntity(params.toJSONString(), ContentType.APPLICATION_JSON));
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(12000).setConnectTimeout(12000).build();
+            httpEntity.setConfig(requestConfig);
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder result = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (client != null) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+
+    public static String KuaiShouttpGetRequest(String url, Map<String, Object> params, Map<String, String> headers) throws Exception {
+        HttpClient httpclient = getHttpclient();
+        String strReturn = "";
+        try {
+
+
+            StringBuilder postBody = new StringBuilder();
+            for (Map.Entry<String, Object> entry : params.entrySet()) {
+                if (entry.getValue() == null) {
+                    continue;
+                }
+                postBody.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue().toString(),
+                        "utf-8")).append("&");
+            }
+            if (!params.isEmpty()) {
+                postBody.deleteCharAt(postBody.length() - 1);
+            }
+
+            HttpGet httpget = new HttpGet(url + "?" + postBody);
+            if (headers != null) {
+                Iterator<String> keyIter = headers.keySet().iterator();
+                while (keyIter.hasNext()) {
+                    String curKey = keyIter.next();
+                    if (curKey != null && headers.get(curKey) != null) {
+                        httpget.addHeader(curKey, headers.get(curKey));
+                    }
+                }
+            }
+            HttpEntity respentity;
+            HttpResponse response = httpclient.execute(httpget);
+            respentity = response.getEntity();
+            strReturn = EntityUtils.toString(respentity);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return strReturn;
+    }
+
+    public static JSONObject feishuGetRequest(String url, JSONObject params) {
+        return feishuGetRequest(null, url, params);
+    }
+
+    public static JSONObject feishuPostRequest(String url, JSONObject params) {
+        return feishuPostRequest(null, url, params);
+    }
+
+    public static String feishuGetRequestString(String url) {
+        // 构造请求
+        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
+            @Override
+            public String getMethod() {
+                return "GET";
+            }
+        };
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setURI(URI.create(url));
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(12000).setConnectTimeout(12000).build();
+            httpEntity.setConfig(requestConfig);
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder result = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return result.toString();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (client != null) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    public static JSONObject feishuGetRequest(String accessToken, String url, JSONObject params) {
+        // 构造请求
+        HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
+            @Override
+            public String getMethod() {
+                return "GET";
+            }
+        };
+        if (accessToken != null) {
+            httpEntity.setHeader("Authorization", accessToken);
+        }
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setURI(URI.create(url));
+            if (params != null) {
+                httpEntity.setEntity(new StringEntity(params.toJSONString(), ContentType.APPLICATION_JSON));
+            }
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(12000).setConnectTimeout(12000).build();
+            httpEntity.setConfig(requestConfig);
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder result = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (client != null) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+
+    public static JSONObject feishuPostRequest(String accessToken, String url, JSONObject params) {
+        // 构造请求
+        HttpPost httpEntity = new HttpPost(url);
+        if (accessToken != null) {
+            httpEntity.setHeader("Authorization", accessToken);
+        }
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setEntity(new StringEntity(params.toJSONString(), ContentType.APPLICATION_JSON));
+            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(12000).setConnectTimeout(12000).build();
+            httpEntity.setConfig(requestConfig);
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuilder result = new StringBuilder();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                if (client != null) {
+                    client.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+}

+ 24 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/common/utils/LinkUtils.java

@@ -37,6 +37,30 @@ public class LinkUtils {
         return result;
     }
 
+    //数据对比,环比计算
+    public static List<JSONObject> getBytedancewCompareDate(List<JSONObject> beforeData, List<JSONObject> AfterData, String standard) {
+        List<JSONObject> result = new ArrayList<>();
+        beforeData.forEach(before -> {
+            String yesStat = String.valueOf(before.get(standard));
+            AfterData.forEach(after -> {
+                if ((String.valueOf(after.get(standard))).equals(yesStat)) {
+                    //消耗较昨日环比
+                    after.put("costProportion", countLink(after.getBigDecimal("cost"), before.getBigDecimal("cost")));
+                    //展示量较昨日环比
+                    after.put("photoShowProportion", countLink(BigDecimal.valueOf(after.getLong("photoShow")), BigDecimal.valueOf(before.getLong("photoShow"))));
+                    //点击量较昨日环比
+                    after.put("photoClickProportion", countLink(BigDecimal.valueOf(after.getLong("photoClick")), BigDecimal.valueOf(before.getLong("photoClick"))));
+                    if(after.getLong("convert")!=null){
+                        after.put("convertProportion", countLink(BigDecimal.valueOf(after.getLong("convert")), BigDecimal.valueOf(before.getLong("convert"))));
+                    }
+                    before.put("afterData", after);
+                }
+            });
+            result.add(before);
+        });
+        return result;
+    }
+
     //环比计算
     public static BigDecimal countLink(BigDecimal numA, BigDecimal numB) {
         BigDecimal link = new BigDecimal(0);

+ 214 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/controller/BytedanceAccountReportDailyDwController.java

@@ -0,0 +1,214 @@
+package cn.com.ctop.report.controller;
+
+import cn.com.ctop.common.constant.AccountReportConstants;
+import cn.com.ctop.common.utils.Check;
+import cn.com.ctop.common.utils.ExportExcelUtils;
+import cn.com.ctop.common.utils.HttpUtils;
+import cn.com.ctop.report.entity.AccountAttributionInfo;
+import cn.com.ctop.report.service.AccountAttributionInfoService;
+import cn.com.ctop.report.service.IBytedanceAccountReportDailyDwService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.DateUtils;
+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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("account/report")
+@Slf4j
+public class BytedanceAccountReportDailyDwController {
+    @Autowired
+    IBytedanceAccountReportDailyDwService accountReportDailyDwService;
+    @Autowired
+    private AccountAttributionInfoService accountAttributionInfoService;
+
+    /**
+     * 查询账户报表数据
+     */
+    @PostMapping("/bytedance/list")
+    public Result<List<JSONObject>> getListReport(@RequestBody JSONObject requestBody) throws ParseException {
+        Result<List<JSONObject>> result = new Result<>();
+        if (requestBody.isEmpty()) {
+            log.error("request body is empty");
+            result.setSuccess(false);
+        }
+        BigDecimal discount = requestBody.getBigDecimal("disscount");
+        JSONArray accounts = requestBody.getJSONArray("accountIds");
+        String userId = requestBody.getString("userId");
+        if (accounts.isEmpty()) {
+            List<AccountAttributionInfo> accountAttributionInfos = accountAttributionInfoService.getAccountInfoList(userId, "bytedance");
+            accounts = new JSONArray();
+            for (AccountAttributionInfo account : accountAttributionInfos) {
+                accounts.add(account.getAccountId());
+            }
+        }
+        String startDate = requestBody.getString("startDate");
+        String endDate = requestBody.getString("endDate");
+        Integer hour = requestBody.getInteger("hour");
+        if (null == hour) {
+            hour = DateUtils.getNowHour();
+        }
+        String target = requestBody.getString("target");
+        String order = requestBody.getString("order");
+        try {
+            List<JSONObject> listData = accountReportDailyDwService.getListDataByParams("1", discount, accounts, startDate, endDate, hour, target, order);
+            result.setResult(listData);
+            result.setSuccess(true);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.setSuccess(false);
+        }
+        return result;
+    }
+
+    /**
+     * 查询素材报表chart数据
+     */
+    @PostMapping("/bytedance/chart")
+    public Result<Map<String, Object>> getAccountChartReport(@RequestBody JSONObject requestBody) {
+        Result<Map<String, Object>> resultBody = new Result<>();
+        Map<String, Object> result = new HashMap<>();
+        if (requestBody.isEmpty()) {
+            log.error("request body is empty");
+            resultBody.setSuccess(false);
+        }
+        String mediaId = requestBody.getString("mediaId");
+        BigDecimal discount = requestBody.getBigDecimal("disscount");
+        JSONArray accounts = requestBody.getJSONArray("accountIds");
+        if (accounts.isEmpty()) {
+            return resultBody;
+        }
+        String startDate = requestBody.getString("startDate");
+        String endDate = requestBody.getString("endDate");
+        try {
+            Map<String, Object> sumData = accountAttributionInfoService.getBytedanceSumDataBy(mediaId, discount, accounts, startDate, endDate);
+            List<JSONObject> chartData = accountAttributionInfoService.getBytedanceChartDataBy(mediaId, discount, accounts, startDate, endDate);
+            result.put("sumData", sumData);
+            result.put("chartData", chartData);
+            resultBody.setResult(result);
+            resultBody.setSuccess(true);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            resultBody.setSuccess(false);
+        }
+        return resultBody;
+    }
+
+
+    @PostMapping("/bytedance/excelV2")
+    public void excelV2(@RequestBody JSONObject requestBody, HttpServletRequest request, HttpServletResponse response) {
+        Result<List<JSONObject>> result = new Result<>();
+        try {
+            if (requestBody.isEmpty()) {
+                log.error("request body is empty");
+                result.setSuccess(false);
+            }
+            BigDecimal discount = requestBody.getBigDecimal("disscount");
+            JSONArray accounts = requestBody.getJSONArray("accountIds");
+            String userId = requestBody.getString("userId");
+            if (accounts.isEmpty()) {
+                List<AccountAttributionInfo> accountAttributionInfos = accountAttributionInfoService.getAccountInfoList(userId, "bytedance");
+                accounts = new JSONArray();
+                for (AccountAttributionInfo account : accountAttributionInfos) {
+                    accounts.add(account.getAccountId());
+                }
+            }
+            String startDate = requestBody.getString("startDate");
+            String endDate = requestBody.getString("endDate");
+            Integer hour = requestBody.getInteger("hour");
+            if (null == hour) {
+                hour = DateUtils.getNowHour();
+            }
+            String target = requestBody.getString("target");
+            String order = requestBody.getString("order");
+            List<JSONObject> listData = accountReportDailyDwService.getListDataByParams("1", discount, accounts, startDate, endDate, hour, target, order);
+
+            JSONArray columns = requestBody.getJSONArray("columns");
+            List<String> columns2 = new ArrayList();
+            columns2.add("statDate");
+            columns2.add("accountId");
+            columns2.add("authName");
+
+            if (!Check.isNull(columns)) {
+                for (int i = 0; i < columns.size(); i++) {
+                    columns2.add(columns.getString(i));
+                }
+            }
+            List<String> titles = getfileIds(AccountReportConstants.getBytedanceVideoFiled(), columns2);
+
+
+            if (Check.isNull(listData)) {
+                throw new Exception("暂无素材相关信息,请检查账户");
+            }
+            List<List<Object>> excelList = new ArrayList<>();
+            for (int i = 0; i < listData.size(); i++) {
+                List<Object> temp = new ArrayList<>();
+                JSONObject jsonObject = listData.get(i);
+                for (int j = 0; j < columns2.size(); j++) {
+                    String key = (String) columns2.get(j);
+                    String value = jsonObject.getString(key);
+                    temp.add(value);
+                }
+                excelList.add(temp);
+            }
+            try {
+                String[] strings = titles.toArray(new String[]{});
+                OutputStream os = response.getOutputStream();
+                ExportExcelUtils eeu = new ExportExcelUtils();
+                XSSFWorkbook workbook = new XSSFWorkbook();
+                eeu.exportExcel(workbook, 0, "头条账户报表", strings, excelList);
+                HttpUtils.setResponseHeader(response, "头条账户报表.xlsx");
+                workbook.write(os);
+                os.flush();
+                os.close();
+            } catch (IOException e) {
+                log.error(e.getMessage());
+            }
+            result.setSuccess(true);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage(), e);
+            result.setSuccess(false);
+            result.setMessage(e.getMessage());
+        }
+
+
+    }
+
+    private List<String> getfileIds(Map<String, Map<String, Object>> kuaishouVideoReportMap, List columns) {
+
+        List<String> titles = new ArrayList<>();
+        for (int i = 0; i < columns.size(); i++) {
+            String string = (String) columns.get(i);
+            Map<String, Object> stringObjectMap = kuaishouVideoReportMap.get(string);
+            if (Check.isNull(stringObjectMap)) {
+                titles.add("-");
+                continue;
+            }
+            Object comment = stringObjectMap.get("comment");
+            titles.add(String.valueOf(comment));
+        }
+
+        return titles;
+    }
+
+
+}

+ 285 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/controller/BytedanceMaterialReportDailyDwController.java

@@ -0,0 +1,285 @@
+package cn.com.ctop.report.controller;
+
+import cn.com.ctop.common.constant.AccountReportConstants;
+import cn.com.ctop.common.mapper.SysRoleMapper;
+import cn.com.ctop.common.service.IProjectMemberService;
+import cn.com.ctop.common.service.IUserAllocationService;
+import cn.com.ctop.common.utils.Check;
+import cn.com.ctop.common.utils.ExportExcelUtils;
+import cn.com.ctop.common.utils.HttpUtils;
+import cn.com.ctop.common.utils.JsonResourceUtil;
+import cn.com.ctop.report.service.IBytedanceMaterialVideoReportDailyDwService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.jeecg.common.api.vo.Result;
+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 javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("material/report")
+@Slf4j
+public class BytedanceMaterialReportDailyDwController {
+    @Autowired
+    IBytedanceMaterialVideoReportDailyDwService bytedanceMaterialVideoReportDailyDwService;
+    @Resource
+    private SysRoleMapper sysRoleMapper;
+    @Autowired
+    private IProjectMemberService projectMemberService;
+    @Autowired
+    private IUserAllocationService userAllocationService;
+
+
+    @PostMapping("/bytedance/list")
+    public Result<PageInfo<JSONObject>> getListReport(@RequestBody JSONObject requestBody) {
+        Result<PageInfo<JSONObject>> result = new Result<>();
+        try {
+            int pageSize = requestBody.getInteger("pageSize");
+            int pageNo = requestBody.getInteger("pageNo");
+            String startDate = requestBody.getString("startDate");
+            String mediaType = requestBody.getString("mediaType");
+            if (Check.isNull(startDate)) {
+                throw new Exception("请输入查询开始时间");
+            }
+            String endDate = requestBody.getString("endDate");
+            if (Check.isNull(endDate)) {
+                throw new Exception("请输入查询结束时间");
+            }
+
+
+            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getBytedanceVideoReportMap());
+            if (Check.isNull(filedAll)) {
+                throw new Exception("初始化查询 字段返回为空");
+            }
+
+            String userId = requestBody.getString("userId");
+            if (Check.isNull(userId)) {
+                throw new Exception("用户id不能为空");
+            }
+            Map<String, Object> requestMap = new HashMap<>();
+            requestMap.put("filed", filedAll);
+            requestMap.put("startDate", Long.parseLong(startDate.replace("-", "")));
+            requestMap.put("endDate", Long.parseLong(endDate.replace("-", "")));
+
+            if (!Check.isNull(requestBody.getJSONArray("accountIds"))) {
+                requestMap.put("accountIds", requestBody.getJSONArray("accountIds"));
+            }
+
+            if (!Check.isNull(requestBody.getString("target"))) {
+                requestMap.put("target", requestBody.getString("target"));
+            }
+            if (!Check.isNull(requestBody.getString("order"))) {
+                requestMap.put("order", requestBody.getString("order"));
+            }
+            if (!Check.isNull(requestBody.getInteger("channelType"))) {
+                requestMap.put("channelType", requestBody.getInteger("channelType"));
+            }
+            String roleCode = sysRoleMapper.getRoleCodeByUserId(userId);
+
+            if (!Check.isNull(requestBody.getString("clipId"))) {
+                requestMap.put("clipId", requestBody.getString("clipId"));
+            }
+            if (!Check.isNull(requestBody.getString("shotId"))) {
+                requestMap.put("shotId", requestBody.getString("shotId"));
+            }
+            if (!Check.isNull(requestBody.getString("planId"))) {
+                requestMap.put("planId", requestBody.getString("planId"));
+            }
+            if (!Check.isNull(requestBody.getString("leaderId"))) {
+                requestMap.put("leaderId", requestBody.getString("leaderId"));
+            }
+
+            PageInfo<JSONObject> listData = bytedanceMaterialVideoReportDailyDwService.getBytedanceVideoPageReportByMap(requestMap, pageSize, pageNo);
+            if (Check.isNull(listData)) {
+                throw new Exception("暂无素材相关信息,请检查账户");
+            }
+            result.setSuccess(true);
+            result.setResult(listData);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.setSuccess(false);
+            result.setMessage(e.toString());
+        }
+        return result;
+    }
+
+    @PostMapping("/bytedance/detail")
+    public Result<List<JSONObject>> getReportDetail(@RequestBody JSONObject requestBody) {
+        Result<List<JSONObject>> result = new Result<>();
+        if (requestBody.isEmpty()) {
+            log.error("request body is empty");
+            result.setSuccess(false);
+        } else {
+
+            JSONArray accountIds = requestBody.getJSONArray("accountIds");
+            String signature = requestBody.getString("signature");
+            String startDate = requestBody.getString("startDate");
+            String endDate = requestBody.getString("endDate");
+            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getDicMapKs());
+            try {
+                if (accountIds.isEmpty()) {
+                    accountIds = null;
+                }
+                List<JSONObject> listData = bytedanceMaterialVideoReportDailyDwService.getVideoDetailBy(accountIds, startDate, endDate, filedAll, signature);
+                result.setResult(listData);
+                result.setSuccess(true);
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                result.setSuccess(false);
+            }
+        }
+        return result;
+    }
+
+
+    @PostMapping("/excelV2")
+    public void excelV2(@RequestBody JSONObject requestBody,
+                        HttpServletRequest request,
+                        HttpServletResponse response) {
+        Result<PageInfo<JSONObject>> result = new Result<>();
+        try {
+            String startDate = requestBody.getString("startDate");
+            if (Check.isNull(startDate)) {
+                throw new Exception("请输入查询开始时间");
+            }
+            String endDate = requestBody.getString("endDate");
+            if (Check.isNull(endDate)) {
+                throw new Exception("请输入查询结束时间");
+            }
+
+
+            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getBytedanceVideoReportMap());
+            if (Check.isNull(filedAll)) {
+                throw new Exception("初始化查询 字段返回为空");
+            }
+
+            String userId = requestBody.getString("userId");
+            if (Check.isNull(userId)) {
+                throw new Exception("用户id不能为空");
+            }
+            Map<String, Object> requestMap = new HashMap<>();
+            requestMap.put("filed", filedAll);
+            requestMap.put("startDate", Long.parseLong(startDate.replace("-", "")));
+            requestMap.put("endDate", Long.parseLong(endDate.replace("-", "")));
+
+            if (!Check.isNull(requestBody.getJSONArray("accountIds"))) {
+                requestMap.put("accountIds", requestBody.getJSONArray("accountIds"));
+            }
+
+            if (!Check.isNull(requestBody.getString("target"))) {
+                requestMap.put("target", requestBody.getString("target"));
+            }
+            if (!Check.isNull(requestBody.getString("order"))) {
+                requestMap.put("order", requestBody.getString("order"));
+            }
+            if (!Check.isNull(requestBody.getInteger("channelType"))) {
+                requestMap.put("channelType", requestBody.getInteger("channelType"));
+            }
+            String roleCode = sysRoleMapper.getRoleCodeByUserId(userId);
+
+            if (!Check.isNull(requestBody.getString("clipId"))) {
+                requestMap.put("clipId", requestBody.getString("clipId"));
+            }
+            if (!Check.isNull(requestBody.getString("shotId"))) {
+                requestMap.put("shotId", requestBody.getString("shotId"));
+            }
+            if (!Check.isNull(requestBody.getString("planId"))) {
+                requestMap.put("planId", requestBody.getString("planId"));
+            }
+            if (!Check.isNull(requestBody.getString("leaderId"))) {
+                requestMap.put("leaderId", requestBody.getString("leaderId"));
+            }
+
+            JSONArray columns = requestBody.getJSONArray("columns");
+            List<String> columns2 = new ArrayList();
+            columns2.add("materialName");
+            columns2.add("signature");
+            columns2.add("projectName");
+            columns2.add("designLeader");
+            columns2.add("clip");
+            columns2.add("plan");
+            columns2.add("shot");
+            columns2.add("purchaseRate");
+            columns2.add("createTime");
+            if (!Check.isNull(columns)) {
+                for (int i = 0; i < columns.size(); i++) {
+                    columns2.add(columns2.size(), columns.getString(i));
+                }
+            }
+            columns2.add(columns2.size(), "url");
+            List<String> titles = getfileIds(AccountReportConstants.getBytedanceVideoFiled(), columns2);
+
+            List<JSONObject> listData = bytedanceMaterialVideoReportDailyDwService.getBytedanceVideoPageReportByMap(requestMap);
+
+
+            if (Check.isNull(listData)) {
+                throw new Exception("暂无素材相关信息,请检查账户");
+            }
+            List<List<Object>> excelList = new ArrayList<>();
+            for (int i = 0; i < listData.size(); i++) {
+                List<Object> temp = new ArrayList<>();
+                JSONObject jsonObject = listData.get(i);
+                for (int j = 0; j < columns2.size(); j++) {
+                    String key = (String) columns2.get(j);
+                    String value = jsonObject.getString(key);
+                    temp.add(value);
+                }
+                excelList.add(temp);
+            }
+            try {
+                String[] strings = titles.toArray(new String[]{});
+                OutputStream os = response.getOutputStream();
+                ExportExcelUtils eeu = new ExportExcelUtils();
+                XSSFWorkbook workbook = new XSSFWorkbook();
+                eeu.exportExcel(workbook, 0, "头条视频素材报表", strings, excelList);
+                HttpUtils.setResponseHeader(response, "头条视频素材.xlsx");
+                workbook.write(os);
+                os.flush();
+                os.close();
+            } catch (IOException e) {
+                log.error(e.getMessage());
+            }
+            result.setSuccess(true);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage(), e);
+            result.setSuccess(false);
+            result.setMessage(e.getMessage());
+        }
+
+
+    }
+
+    private List<String> getfileIds(Map<String, Map<String, Object>> kuaishouVideoReportMap, List columns) {
+
+        List<String> titles = new ArrayList<>();
+        for (int i = 0; i < columns.size(); i++) {
+            String string = (String) columns.get(i);
+            Map<String, Object> stringObjectMap = kuaishouVideoReportMap.get(string);
+            if (Check.isNull(stringObjectMap)) {
+                titles.add("-");
+                continue;
+            }
+            Object comment = stringObjectMap.get("comment");
+            titles.add(String.valueOf(comment));
+        }
+
+        return titles;
+    }
+}

+ 1 - 1
jeecg-boot-report/src/main/java/cn/com/ctop/report/controller/KuaishouAccountReportDailyDwController.java

@@ -61,7 +61,7 @@ public class KuaishouAccountReportDailyDwController {
         JSONArray accounts = requestBody.getJSONArray("accountIds");
         String userId = requestBody.getString("userId");
         if (accounts.isEmpty()) {
-            List<AccountAttributionInfo> accountAttributionInfos = accountAttributionInfoService.getAccountInfoList(userId,"1");
+            List<AccountAttributionInfo> accountAttributionInfos = accountAttributionInfoService.getAccountInfoList(userId,"kuaishou");
             accounts = new JSONArray();
             for (AccountAttributionInfo account:accountAttributionInfos) {
                 accounts.add(account.getAccountId());

+ 22 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/AccountAttributionInfoMapper.java

@@ -18,18 +18,40 @@ public interface AccountAttributionInfoMapper extends BaseMapper<AccountAttribut
     //今日汇总数据
     JSONObject queryTodaySumReportBy(@Param("statDate") Long statDate, @Param("accountIds") JSONArray accountIds);
 
+    //今日汇总数据
+    JSONObject queryBytedanceTodaySumReportBy(@Param("statDate") Long statDate, @Param("accountIds") JSONArray accountIds);
+
+
     //根据小时区间查询今日汇总数据
     JSONObject queryTodaySumByHour(@Param("statDate") Long statDate, @Param("hour") int hour, @Param("accountIds") JSONArray accountIds);
 
+    //根据小时区间查询今日汇总数据
+    JSONObject queryBytedanceTodaySumByHour(@Param("statDate") Long statDate, @Param("hour") int hour, @Param("accountIds") JSONArray accountIds);
+
+
     //根据开始、结束时间 查询汇总数据
     JSONObject querySumByStartEndDate(@Param("endDate") Long endDate, @Param("startDate") Long startDate, @Param("accountIds") JSONArray accountIds);
 
+    //根据开始、结束时间 查询汇总数据
+    JSONObject queryBuytedanceSumByStartEndDate(@Param("endDate") Long endDate, @Param("startDate") Long startDate, @Param("accountIds") JSONArray accountIds);
+
     //今日明细数据
     List<JSONObject> queryTodayDetailReportBy(@Param("filed") String filed, @Param("statDate") Long statDate, @Param("accountIds") JSONArray accountIds);
 
+
+    //今日明细数据
+    List<JSONObject> queryBytedanceTodayDetailReportBy(@Param("filed") String filed, @Param("statDate") Long statDate, @Param("accountIds") JSONArray accountIds);
+
     //按月分组查询明细数据
     List<JSONObject> queryDetailGroupMonthByDate(@Param("endDate") Long endDate, @Param("startDate") Long startDate, @Param("accountIds") JSONArray accountIds);
 
+    //按月分组查询明细数据
+    List<JSONObject> queryBytedanceDetailGroupMonthByDate(@Param("endDate") Long endDate, @Param("startDate") Long startDate, @Param("accountIds") JSONArray accountIds);
+
     //根据开始、结束时间 查询明细数据
     List<JSONObject> queryDetailByStartEndDate(@Param("endDate") Long endDate, @Param("startDate") Long startDate, @Param("accountIds") JSONArray accountIds);
+
+    //根据开始、结束时间 查询明细数据
+    List<JSONObject> queryBytedanceDetailByStartEndDate(@Param("endDate") Long endDate, @Param("startDate") Long startDate, @Param("accountIds") JSONArray accountIds);
+
 }

+ 13 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/BytedanceAccountReportDailyDwMapper.java

@@ -0,0 +1,13 @@
+package cn.com.ctop.report.mapper;
+
+import cn.com.ctop.report.entity.KuaishouAccountReportDailyDw;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface BytedanceAccountReportDailyDwMapper  {
+    List<JSONObject> getReportByParams(@Param(value = "filedAll") String filedAll, @Param(value = "endDate") Long endDate, @Param(value = "startDate") Long startDate, @Param(value = "accountIds") JSONArray accounts, @Param(value = "target") String target, @Param(value = "order") String order, @Param(value = "hasGroupBy") int hasGroupBy, @Param(value = "groupBy") String groupBy);
+}

+ 13 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/BytedanceAccountReportHourlyDwMapper.java

@@ -0,0 +1,13 @@
+package cn.com.ctop.report.mapper;
+
+import cn.com.ctop.report.entity.KuaishouAccountReportHourlyDw;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface BytedanceAccountReportHourlyDwMapper  {
+    List<JSONObject> getReportByParams(@Param(value = "filedAll") String filedAll, @Param(value = "startDate") Long startDate, @Param(value = "hour") int hour, @Param(value = "accountIds") JSONArray accounts, @Param(value = "target") String target, @Param(value = "order") String order, @Param(value = "hasGroupBy") int hasGroupBy, @Param(value = "groupBy") String groupBy);
+}

+ 18 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/BytedanceMaterialVideoReportDailyDwMapper.java

@@ -0,0 +1,18 @@
+package cn.com.ctop.report.mapper;
+
+import cn.com.ctop.report.entity.KuaishouMaterialVideoReportDailyDw;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+public interface BytedanceMaterialVideoReportDailyDwMapper {
+    Long getTotalByMap(Map<String, Object> requestMap);
+
+    List<JSONObject> getBytedanceVideoReportByMap(Map<String, Object> requestMap);
+
+    List<JSONObject> queryVideoDetailBy(@Param("accountIds") JSONArray accountIds, @Param("startDate") String startDate, @Param("endDate") String endDate, @Param("filed") String filed, @Param("signature") String signature);
+}

+ 117 - 1
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/AccountAttributionInfoMapper.xml

@@ -88,6 +88,24 @@
                 #{item}
             </foreach>
         </select>
+        <select id="queryBytedanceTodaySumReportBy" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            ROUND(sum(cost),3) cost,
+            sum(click) photoClick,
+            sum(`show`) photoShow,
+            sum(`convert`) as `convert`,
+        max(`hour`) maxHour
+        FROM
+            bytedance_advertiser_report_hourly_dw
+        WHERE
+            stat_datetime = #{statDate}
+        AND account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
+
 
         <select id="queryTodaySumByHour" resultType="com.alibaba.fastjson.JSONObject">
             SELECT
@@ -106,6 +124,24 @@
                 #{item}
             </foreach>
         </select>
+    <select id="queryBytedanceTodaySumByHour" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        IFNULL(ROUND(sum(cost),2),0)  cost,
+        IFNULL(sum(`show`),0)  photoShow,
+        IFNULL(sum(click),0)  photoClick,
+        IFNULL(sum(`convert`),0)  as `convert`
+        FROM
+        bytedance_advertiser_report_hourly_dw
+        WHERE
+        stat_datetime = #{statDate}
+        AND `hour` &lt;= #{hour}
+        AND account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
+
 
 
         <select id="queryTodayDetailReportBy" resultType="com.alibaba.fastjson.JSONObject">
@@ -129,6 +165,28 @@
             ORDER BY
             `hour` ASC
         </select>
+    <select id="queryBytedanceTodayDetailReportBy" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        ROUND(sum(cost),3) cost,
+        sum(`show`) photoShow,
+        sum(click) photoClick,
+        sum(`convert`) as `convert`,
+        `hour` as statHour
+        FROM
+        bytedance_advertiser_report_hourly_dw
+        WHERE
+        stat_datetime = #{statDate}
+        AND account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        GROUP BY
+        `hour`
+        ORDER BY
+        `hour` ASC
+    </select>
+
 
 
         <select id="querySumByStartEndDate" resultType="com.alibaba.fastjson.JSONObject">
@@ -146,6 +204,21 @@
                 #{item}
             </foreach>
         </select>
+        <select id="queryBuytedanceSumByStartEndDate" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            sum(cost) cost,
+            sum(`show`) photoShow,
+            sum(click) photoClick,
+            sum(`convert`) as `convert`
+        FROM bytedance_advertiser_report_daily_dw t1
+        WHERE t1.stat_datetime &lt;= #{endDate}
+        AND t1.stat_datetime &gt;= #{startDate}
+        AND account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </select>
 
 
 
@@ -169,6 +242,28 @@
             order by stat_date asc
         </select>
 
+    <select id="queryBytedanceDetailByStartEndDate" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        ROUND(sum(cost),3) cost,
+        sum(`show`) photoShow,
+        sum(click) photoClick,
+        sum(`convert`) as `convert`,
+        stat_datetime as stat_datetime
+        FROM
+        bytedance_advertiser_report_daily_dw
+        WHERE stat_datetime &lt;= #{endDate}
+        AND stat_datetime &gt;= #{startDate}
+        AND account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        group by stat_datetime
+        order by stat_datetime asc
+    </select>
+
+
+
         <select id="queryDetailGroupMonthByDate" resultType="com.alibaba.fastjson.JSONObject">
             SELECT
             ROUND(sum(charge),3) cost,
@@ -185,6 +280,27 @@
                 #{item}
             </foreach>
             group by DATE_FORMAT(t1.stat_date, '%Y-%m')
-            order by t1.stat_date asc
+            order by t1.stat_datetime asc
         </select>
+
+    <select id="queryBytedanceDetailGroupMonthByDate" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        ROUND(sum(cost),3) cost,
+        sum(`show`) photoShow,
+        sum(click) photoClick,
+        sum(`convert`) as `convert`,
+        DATE_FORMAT(t1.stat_datetime, '%Y-%m') statDate
+        FROM bytedance_advertiser_report_daily_dw t1
+        WHERE t1.stat_datetime &lt;= #{endDate}
+        AND t1.stat_datetime &gt;= #{startDate}
+        AND t1.account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        group by DATE_FORMAT(t1.stat_datetime, '%Y-%m')
+        order by t1.stat_datetime asc
+    </select>
+
+
 </mapper>

+ 26 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/BytedanceAccountReportDailyDwMapper.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.report.mapper.BytedanceAccountReportDailyDwMapper">
+
+    <select id="getReportByParams" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        stat_datetime as statDate,
+        account_id as accountId,
+        account_name as authName,
+        ${filedAll}
+        FROM
+        bytedance_advertiser_report_daily_dw
+        WHERE
+        stat_datetime &lt;= #{endDate}
+        AND stat_datetime &gt;= #{startDate}
+        AND account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        <if test="hasGroupBy == 1">
+            group by ${groupBy}
+            order by ${target} ${order}
+        </if>
+    </select>
+</mapper>

+ 24 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/BytedanceAccountReportHourlyDwMapper.xml

@@ -0,0 +1,24 @@
+<?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.report.mapper.BytedanceAccountReportHourlyDwMapper">
+
+    <select id="getReportByParams" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        stat_datetime as statDate,
+        account_id as accountId,
+        account_name as authName,
+        ${filedAll}
+        FROM bytedance_advertiser_report_hourly_dw t1
+        WHERE t1.stat_datetime = #{startDate}
+        and t1.`hour` &lt;= #{hour}
+        AND t1.account_id in
+        <foreach item="item" index="index" collection="accountIds"
+                 open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        <if test="hasGroupBy == 1">
+            group by t1.account_id
+        </if>
+        order by ${target} ${order}
+    </select>
+</mapper>

+ 122 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/mapper/xml/BytedanceMaterialVideoReportDailyDwMapper.xml

@@ -0,0 +1,122 @@
+<?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.report.mapper.BytedanceMaterialVideoReportDailyDwMapper">
+
+
+
+    <select id="getTotalByMap" resultType="java.lang.Long">
+        SELECT
+        count(1)
+        FROM
+        (select
+        t1.signature
+        from bytedance_material_video_report_daily_dw t1
+        where 1 = 1
+        <if test="accountIds !=null and accountIds != ''">
+            and t1.account_id in
+            <foreach item="item" index="index" collection="accountIds"
+                     open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        <if test="startDate !=null and startDate != ''">
+            AND t1.stat_datetime &gt;= #{startDate}
+        </if>
+        <if test="endDate !=null and endDate != ''">
+            AND t1.stat_datetime &lt;= #{endDate}
+        </if>
+        <if test="leaderId !=null and leaderId != ''">
+            AND t1.leader_id = #{leaderId}
+        </if>
+        <if test="clipId !=null and clipId != ''">
+            AND t1.clip_id = #{clipId}
+        </if>
+        <if test="planId !=null and planId != ''">
+            AND t1.plan_id = #{planId}
+        </if>
+        <if test="shotId !=null and shotId != ''">
+            AND t1.shot_id = #{shotId}
+        </if>
+        <if test="companyId !=null and companyId != ''">
+            AND t1.company_id = #{companyId}
+        </if>
+        GROUP BY t1.signature
+        ) t2
+    </select>
+    <select id="getBytedanceVideoReportByMap" resultType="com.alibaba.fastjson.JSONObject" parameterType="map">
+        SELECT
+        t1.*
+        FROM
+        (select
+        IFNULL( clip_name, '-' ) AS clip,
+        IFNULL( plan_name, '-' ) AS plan,
+        IFNULL( shot_name, '-' ) AS shot,
+        IFNULL( leader_name, '-' ) AS designLeader,
+        IFNULL( video_name, '-' ) AS materialName,
+        IFNULL( cover_url, '-' ) AS coverUrl,
+        IFNULL( video_url, '-' ) AS url,
+        IFNULL( stat_datetime, '-' ) AS createTime,
+        ${filed}
+        from bytedance_material_video_report_daily_dw
+        where 1 = 1
+        <if test="accountIds !=null and accountIds != ''">
+            and account_id in
+            <foreach item="item" index="index" collection="accountIds"
+                     open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        <if test="startDate !=null and startDate != ''">
+            AND stat_datetime &gt;= #{startDate}
+        </if>
+        <if test="endDate !=null and endDate != ''">
+            AND stat_datetime &lt;= #{endDate}
+        </if>
+        <if test="leaderId !=null and leaderId != ''">
+            AND leader_id = #{leaderId}
+        </if>
+        <if test="clipId !=null and clipId != ''">
+            AND clip_id = #{clipId}
+        </if>
+        <if test="planId !=null and planId != ''">
+            AND plan_id = #{planId}
+        </if>
+        <if test="shotId !=null and shotId != ''">
+            AND shot_id = #{shotId}
+        </if>
+        <if test="companyId !=null and companyId != ''">
+            AND clip_company_id = #{companyId}
+        </if>
+        GROUP BY signature
+        ORDER BY ${target} ${order}
+        ) t1
+
+
+    </select>
+    <select id="queryVideoDetailBy" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        t1.stat_date as statDate,
+        t1.signature,
+        t1.photo_url as url,
+        t1.cover_url as converUrl,
+        (select t2.material_name from ctop_material_info t2 where t2.code=t1.signature limit 1) AS materialName,
+        t1.project_name AS projectName,
+        t1.advertiser_name AS advertiserName,
+        (select t2.create_time from ctop_material_info t2 where t2.code=t1.signature limit 1) as createTime,
+        ${filed}
+        FROM
+        bytedance_material_video_report_daily_dw t1
+        WHERE t1.signature=#{signature}
+        AND t1.stat_date >= #{startDate}
+        AND t1.stat_date &lt;= #{endDate}
+        <if test="accountIds != null">
+            AND t1.account_id in
+            <foreach item="item" index="index" collection="accountIds"
+                     open="(" separator="," close=")">
+                #{item}
+            </foreach>
+        </if>
+        GROUP BY t1.signature,t1.stat_date
+        order by t1.stat_date desc
+    </select>
+</mapper>

+ 4 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/service/AccountAttributionInfoService.java

@@ -24,5 +24,9 @@ public interface AccountAttributionInfoService extends IService<AccountAttributi
 
     Map<String,Object> getSumDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate);
 
+    Map<String,Object> getBytedanceSumDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate);
+
     List<JSONObject> getChartDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) throws ParseException, ParseException;
+    List<JSONObject> getBytedanceChartDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) throws ParseException, ParseException;
+
 }

+ 14 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/service/IBytedanceAccountReportDailyDwService.java

@@ -0,0 +1,14 @@
+package cn.com.ctop.report.service;
+
+import cn.com.ctop.report.entity.KuaishouAccountReportDailyDw;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+public interface IBytedanceAccountReportDailyDwService  {
+
+    List<JSONObject> getListDataByParams(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate, int hour, String target, String order);
+}

+ 16 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/service/IBytedanceMaterialVideoReportDailyDwService.java

@@ -0,0 +1,16 @@
+package cn.com.ctop.report.service;
+
+import cn.com.ctop.report.entity.KuaishouMaterialVideoReportDailyDw;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.pagehelper.PageInfo;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IBytedanceMaterialVideoReportDailyDwService  {
+    PageInfo<JSONObject> getBytedanceVideoPageReportByMap(Map<String, Object> requestMap, int pageSize, int pageNo);
+    List<JSONObject> getBytedanceVideoPageReportByMap(Map<String, Object> requestMap);
+    List<JSONObject> getVideoDetailBy(JSONArray accountIds, String startDate, String endDate, String filedAll, String signature);
+}

+ 106 - 2
jeecg-boot-report/src/main/java/cn/com/ctop/report/service/impl/AccountAttributionInfoServiceImpl.java

@@ -230,6 +230,37 @@ public class AccountAttributionInfoServiceImpl extends ServiceImpl<AccountAttrib
     }
 
     @Override
+    public Map<String, Object> getBytedanceSumDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) {
+        Map<String, Object> result = new HashMap<>();
+        JSONObject after;
+        JSONObject before;
+        Long startDateNum = Long.parseLong(startDate.replace("-",""));
+        Long anotherStartDateNum = Long.parseLong(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1).replace("-",""));
+
+        Long endDateNum = Long.parseLong(endDate.replace("-",""));
+        Long anotherEndDateNum = Long.parseLong(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, endDate, -1).replace("-",""));
+        if (startDateNum.equals(endDateNum)) {
+            after = accountAttributionInfoMapper.queryBytedanceTodaySumReportBy(startDateNum, accounts);
+            if (after == null) {
+                return result;
+            }
+            before = accountAttributionInfoMapper.queryBytedanceTodaySumByHour(anotherStartDateNum, after.getInteger("maxHour"), accounts);
+            if (before == null) {
+                before = after;
+            }
+        } else {
+            after = accountAttributionInfoMapper.queryBuytedanceSumByStartEndDate(endDateNum, startDateNum, accounts);
+            if (after == null) {
+                return result;
+            }
+            before = after;
+        }
+        return getBytedanceSumLink(mediaId, discount, after, before);
+
+    }
+
+
+    @Override
     public List<JSONObject> getChartDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) throws ParseException {
         List<JSONObject> result = new ArrayList<>();
         String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getDicMapKs());
@@ -266,6 +297,45 @@ public class AccountAttributionInfoServiceImpl extends ServiceImpl<AccountAttrib
         return result;
     }
 
+    @Override
+    public List<JSONObject> getBytedanceChartDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) throws ParseException {
+        List<JSONObject> result = new ArrayList<>();
+        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getDicMapKs());
+        Long startDateNum = Long.parseLong(startDate.replace("-",""));
+        Long anotherStartDateNum = Long.parseLong(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1).replace("-",""));
+
+        Long endDateNum = Long.parseLong(endDate.replace("-",""));
+        Long anotherEndDateNum = Long.parseLong(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, endDate, -1).replace("-",""));
+        if (startDateNum.equals(endDateNum)) {
+            List<JSONObject> after = accountAttributionInfoMapper.queryBytedanceTodayDetailReportBy(filedAll, startDateNum, accounts);
+            List<JSONObject> before = accountAttributionInfoMapper.queryBytedanceTodayDetailReportBy(filedAll, anotherStartDateNum, accounts);
+            if (after.size() == 0) {
+                return result;
+            }
+            if (before.size() == 0) {
+                before = nullDataHandle();
+            }
+            List<JSONObject> afterDis = this.countDiscountCost(mediaId, discount, after);
+            List<JSONObject> beforeDis = this.countDiscountCost(mediaId, discount, before);
+            //result = LinkUtils.getBytedancewCompareDate(beforeDis, afterDis, "statHour");
+            result = afterDis;
+        } else {
+            List<JSONObject> after;
+            //判断是不是日期间隔大于半年
+            if (DateUtils.isMoreSixMonth(startDate, endDate)) {
+                after = accountAttributionInfoMapper.queryBytedanceDetailGroupMonthByDate(endDateNum, startDateNum, accounts);
+            } else {
+                after = accountAttributionInfoMapper.queryBytedanceDetailByStartEndDate(endDateNum, startDateNum, accounts);
+            }
+            if (after == null) {
+                return result;
+            }
+            result = this.countDiscountCost(mediaId, discount, after);
+        }
+        return result;
+    }
+
+
     //计算汇总数据环比
     private Map<String, Object> getSumLink(String mediaId, BigDecimal discount, JSONObject after, JSONObject before) {
 
@@ -300,6 +370,40 @@ public class AccountAttributionInfoServiceImpl extends ServiceImpl<AccountAttrib
         return result;
     }
 
+    //计算汇总数据环比
+    private Map<String, Object> getBytedanceSumLink(String mediaId, BigDecimal discount, JSONObject after, JSONObject before) {
+
+        Map<String, Object> result = new HashMap<>();
+
+        JSONObject costLink = new JSONObject();
+        JSONObject discountCostLink = new JSONObject();
+        JSONObject photoClickLink = new JSONObject();
+        JSONObject photoShowLink = new JSONObject();
+        JSONObject convertLink = new JSONObject();
+
+        costLink.put("cost", after.getBigDecimal("cost"));
+        costLink.put("costSumLink", LinkUtils.countLink(after.getBigDecimal("cost"), before.getBigDecimal("cost")));
+        if (mediaId.equals(CtopAdConstant.PLATFORM_TYPE_KUAISHOU)) {
+            discountCostLink.put("discountCost", after.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP));
+            discountCostLink.put("discountCostLink", LinkUtils.countLink(after.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP), before.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP)));
+        } else {
+            discountCostLink.put("discountCost", after.getBigDecimal("cost").divide(discount,2, RoundingMode.HALF_UP));
+            discountCostLink.put("discountCostLink", LinkUtils.countLink(after.getBigDecimal("cost").divide(discount,2, RoundingMode.HALF_UP), before.getBigDecimal("cost").divide(discount,2, RoundingMode.HALF_UP)));
+        }
+        photoClickLink.put("photoClick", after.getBigDecimal("photoClick"));
+        photoClickLink.put("photoClickLink", LinkUtils.countLink(after.getBigDecimal("photoClick"), before.getBigDecimal("photoClick")));
+        photoShowLink.put("photoShow", after.getBigDecimal("photoShow"));
+        photoShowLink.put("photoShowLink", LinkUtils.countLink(after.getBigDecimal("photoShow"), before.getBigDecimal("photoShow")));
+        convertLink.put("convert", after.getBigDecimal("convert"));
+        convertLink.put("convertLink", LinkUtils.countLink(after.getBigDecimal("convert"), before.getBigDecimal("convert")));
+        result.put("costLink", costLink);
+        result.put("discountCostLink", discountCostLink);
+        result.put("photoClickLink", photoClickLink);
+        result.put("photoShowLink", photoShowLink);
+        result.put("convertLink", convertLink);
+        return result;
+    }
+
     //计算折后消耗
     private List<JSONObject> countDiscountCost(String mediaId, BigDecimal discount, List<JSONObject> data) {
         if (data.isEmpty()) {
@@ -307,11 +411,11 @@ public class AccountAttributionInfoServiceImpl extends ServiceImpl<AccountAttrib
         }
         if (mediaId.equals(CtopAdConstant.PLATFORM_TYPE_KUAISHOU)) {
             data.forEach(it -> {
-                it.put("discountCost", it.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP));
+                it.put("discountCost", it.getBigDecimal("cost").divide(discount, 3, RoundingMode.HALF_UP));
             });
         } else {
             data.forEach(it -> {
-                it.put("discountCost", it.getBigDecimal("cost").multiply(discount));
+                it.put("discountCost", it.getBigDecimal("cost").divide(discount, 2, RoundingMode.HALF_UP));
             });
         }
         return data;

+ 104 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/service/impl/BytedanceAccountReportDailyDwServiceImpl.java

@@ -0,0 +1,104 @@
+package cn.com.ctop.report.service.impl;
+
+import cn.com.ctop.common.constant.AccountReportConstants;
+import cn.com.ctop.common.utils.JsonResourceUtil;
+import cn.com.ctop.common.utils.LinkUtils;
+import cn.com.ctop.report.mapper.BytedanceAccountReportDailyDwMapper;
+import cn.com.ctop.report.mapper.BytedanceAccountReportHourlyDwMapper;
+import cn.com.ctop.report.service.IBytedanceAccountReportDailyDwService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.jeecg.common.constant.SystemDateConstant;
+import org.jeecg.common.util.DateUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+
+@Service
+public class BytedanceAccountReportDailyDwServiceImpl implements IBytedanceAccountReportDailyDwService {
+
+    @Resource
+    private BytedanceAccountReportDailyDwMapper bytedanceAccountReportDailyDwMapper;
+    @Resource
+    private BytedanceAccountReportHourlyDwMapper bytedanceAccountReportHourlyDwMapper;
+
+    @Override
+    public List<JSONObject> getListDataByParams(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate, int hour, String target, String order) {
+        List<JSONObject> result;
+        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getBytedanceAccountReportMap());
+        Long startDateNum = Long.parseLong(startDate.replace("-", ""));
+        Long anotherStartDateNum = Long.parseLong(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1).replace("-", ""));
+
+        Long endDateNum = Long.parseLong(endDate.replace("-", ""));
+        Long anotherEndDateNum = Long.parseLong(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, endDate, -1).replace("-", ""));
+
+        if (startDateNum.equals(endDateNum)) {
+            String groupBy = "account_id";
+            if (startDate.equals(DateUtils.date2Str())) {
+                result = bytedanceAccountReportHourlyDwMapper.getReportByParams(filedAll, startDateNum, hour, accounts, target, order, 1, groupBy);
+                JSONObject afterSum = bytedanceAccountReportHourlyDwMapper.getReportByParams(filedAll, startDateNum, hour, accounts, target, order, 0, groupBy).get(0);
+                JSONObject beforeSum = bytedanceAccountReportHourlyDwMapper.getReportByParams(filedAll, anotherStartDateNum, hour, accounts, target, order, 0, groupBy).get(0);
+                if(result.size()>0){
+                    afterSum.put("statDate","总计");
+                    afterSum.put("accountId","-");
+                    afterSum.put("authName","-");
+
+                    beforeSum.put("statDate","昨日总计-(相-对)");
+                    beforeSum.put("accountId","-");
+                    beforeSum.put("authName","-");
+                    result.add(afterSum);
+                    result.add(beforeSum);
+                }
+
+            } else {
+                result = bytedanceAccountReportDailyDwMapper.getReportByParams(filedAll, endDateNum, startDateNum, accounts, target, order, 1, groupBy);
+                JSONObject afterSum = bytedanceAccountReportDailyDwMapper.getReportByParams(filedAll, endDateNum, startDateNum, accounts, target, order, 0, groupBy).get(0);
+                JSONObject beforeSum = bytedanceAccountReportDailyDwMapper.getReportByParams(filedAll, anotherEndDateNum, anotherStartDateNum, accounts, target, order, 0, groupBy).get(0);
+                if(result.size()>0){
+                    afterSum.put("statDate","总计");
+                    afterSum.put("accountId","-");
+                    afterSum.put("authName","-");
+
+                    beforeSum.put("statDate","昨日总计-(相-对)");
+                    beforeSum.put("accountId","-");
+                    beforeSum.put("authName","-");
+
+                    result.add(afterSum);
+                    result.add(beforeSum);
+                }
+            }
+        } else {
+            String groupBy = "stat_datetime";
+            if (accounts.size() > 1) {
+                groupBy = "account_id";
+            }
+            result = bytedanceAccountReportDailyDwMapper.getReportByParams(filedAll, endDateNum, startDateNum, accounts, target, order, 1, groupBy);
+            List<JSONObject> totalList = bytedanceAccountReportDailyDwMapper.getReportByParams(filedAll, endDateNum, startDateNum, accounts, target, order, 0, groupBy);
+            if (result.size() > 0 && null != totalList && !totalList.isEmpty()) {
+                JSONObject jsonObject= totalList.get(0);
+                jsonObject.put("statDate","总计");
+                jsonObject.put("accountId","-");
+                jsonObject.put("authName","-");
+                result.add(jsonObject);
+            }
+        }
+        return result;
+    }
+
+    //计算总计环比
+    private JSONObject countTotal(JSONObject after, JSONObject before) {
+        JSONObject jsonObject = new JSONObject();
+        after.forEach((k, v) -> {
+            //去除没法计算的字段
+            if ("accountId".equals(k) || "authName".equals(k) || "projectName".equals(k) || "statDate".equals(k) || v.toString().contains("%") || before.getString(k).contains("%")) {
+                jsonObject.put(k, "-");
+            } else {
+                jsonObject.put(k, (LinkUtils.countLink(after.getBigDecimal(k) == null ? BigDecimal.ZERO : after.getBigDecimal(k), before.getBigDecimal(k) == null ? BigDecimal.ZERO : before.getBigDecimal(k))).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP) + "%");
+            }
+        });
+        return jsonObject;
+    }
+}

+ 38 - 0
jeecg-boot-report/src/main/java/cn/com/ctop/report/service/impl/BytedanceMaterialVideoReportDailyDwServiceImpl.java

@@ -0,0 +1,38 @@
+package cn.com.ctop.report.service.impl;
+
+import cn.com.ctop.report.mapper.BytedanceMaterialVideoReportDailyDwMapper;
+import cn.com.ctop.report.service.IBytedanceMaterialVideoReportDailyDwService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class BytedanceMaterialVideoReportDailyDwServiceImpl implements IBytedanceMaterialVideoReportDailyDwService {
+    @Resource
+    private BytedanceMaterialVideoReportDailyDwMapper materialVideoReportDailyDwMapper;
+
+    @Override
+    public PageInfo<JSONObject> getBytedanceVideoPageReportByMap(Map<String, Object> requestMap, int pageSize, int pageNo) {
+        Long total = materialVideoReportDailyDwMapper.getTotalByMap(requestMap);
+        PageHelper.startPage(pageNo, pageSize, false);
+        PageInfo pageInfo = new PageInfo(materialVideoReportDailyDwMapper.getBytedanceVideoReportByMap(requestMap));
+        pageInfo.setTotal(total);
+        return pageInfo;
+    }
+
+    @Override
+    public List<JSONObject> getBytedanceVideoPageReportByMap(Map<String, Object> requestMap) {
+        return materialVideoReportDailyDwMapper.getBytedanceVideoReportByMap(requestMap);
+    }
+
+    @Override
+    public List<JSONObject> getVideoDetailBy(JSONArray accountIds, String startDate, String endDate, String filedAll, String signature) {
+        return materialVideoReportDailyDwMapper.queryVideoDetailBy(accountIds, startDate, endDate, filedAll, signature);
+    }
+}