فهرست منبع

初始化代码

songyh 4 سال پیش
والد
کامیت
5dde428b24
67فایلهای تغییر یافته به همراه5232 افزوده شده و 99 حذف شده
  1. 2 2
      jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  2. 2 2
      jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java
  3. 2 2
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java
  4. 21 13
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java
  5. 18 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/Dict.java
  6. 27 37
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
  7. 1 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAdvertisePlan.java
  8. 1 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCreative.java
  9. 1 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceVideoInfo.java
  10. 1 3
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceImageInfo.java
  11. 21 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceAdvertisePlanMapper.java
  12. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceAdvertiserMapper.java
  13. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceAudiencePackageMapper.java
  14. 17 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceCampaignMapper.java
  15. 18 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceCreativeMapper.java
  16. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceCreativeMaterialMapper.java
  17. 21 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceVideoInfoMapper.java
  18. 22 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/BytedanceImageInfoMapper.java
  19. 25 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceAdvertisePlanMapper.xml
  20. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceAdvertiserMapper.xml
  21. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceAudiencePackageMapper.xml
  22. 37 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceCampaignMapper.xml
  23. 48 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceCreativeMapper.xml
  24. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceCreativeMaterialMapper.xml
  25. 69 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceVideoInfoMapper.xml
  26. 49 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/BytedanceImageInfoMapper.xml
  27. 48 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertisePlanService.java
  28. 48 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertiserDataService.java
  29. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertiserService.java
  30. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAudiencePackageService.java
  31. 22 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCampaignService.java
  32. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCreativeMaterialService.java
  33. 34 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCreativeService.java
  34. 21 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceVideoInfoService.java
  35. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IBytedanceBidWarningService.java
  36. 18 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IBytedanceImageInfoService.java
  37. 470 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertisePlanServiceImpl.java
  38. 790 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertiserDataServiceImpl.java
  39. 18 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertiserServiceImpl.java
  40. 18 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceByteDanceAudiencePackageServiceImpl.java
  41. 249 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceCampaignServiceImpl.java
  42. 20 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceCreativeMaterialServiceImpl.java
  43. 907 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceCreativeServiceImpl.java
  44. 44 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceVideoInfoServiceImpl.java
  45. 32 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/BytedanceImageInfoServiceImpl.java
  46. 12 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/vo/BytedanceCampaignEditVo.java
  47. 15 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/vo/BytedanceVideoVo.java
  48. 4 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/aa.java
  49. 136 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/entity/CtopOauthToken.java
  50. 59 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/CtopOauthTokenMapper.java
  51. 139 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/xml/CtopOauthTokenMapper.xml
  52. 35 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/ICtopOauthTokenService.java
  53. 166 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/CtopOauthTokenServiceImpl.java
  54. 66 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/Check.java
  55. 1 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/utils/CtopAdConstant.java
  56. 28 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/HttpGetWithBodyEntity.java
  57. 955 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/HttpUtils.java
  58. 64 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/PropertiesUtils.java
  59. 31 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/ResultMapUtils.java
  60. 124 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/StatusCode.java
  61. 111 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/StringUtils.java
  62. 2 4
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
  63. 6 8
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java
  64. 9 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml
  65. 7 7
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java
  66. 7 10
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java
  67. 9 9
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java

+ 2 - 2
jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -353,7 +353,7 @@ public interface ISysBaseAPI extends CommonAPI {
      * @return
      */
     @GetMapping("/sys/api/translateDictFromTable")
-    String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key);
+    String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key,@RequestParam("extendsKey") String extendsKey, @RequestParam("extendsValue") String extendsValue);
 
     /**
      * 41普通字典的翻译
@@ -362,7 +362,7 @@ public interface ISysBaseAPI extends CommonAPI {
      * @return
      */
     @GetMapping("/sys/api/translateDict")
-    String translateDict(@RequestParam("code") String code, @RequestParam("key") String key);
+    String translateDict(@RequestParam("code") String code, @RequestParam("key") String key,@RequestParam("extendsKey") String extendsKey, @RequestParam("extendsValue") String extendsValue);
 
     /**
      * 42查询数据权限

+ 2 - 2
jeecg-boot-base/jeecg-boot-base-api/jeecg-system-cloud-api/src/main/java/org/jeecg/common/system/api/fallback/SysBaseAPIFallback.java

@@ -221,12 +221,12 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
     }
 
     @Override
-    public String translateDictFromTable(String table, String text, String code, String key) {
+    public String translateDictFromTable(String table, String text, String code, String key,String ekey,String evalue) {
         return null;
     }
 
     @Override
-    public String translateDict(String code, String key) {
+    public String translateDict(String code, String key,String ekey,String evalue) {
         return null;
     }
 

+ 2 - 2
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/api/CommonAPI.java

@@ -54,7 +54,7 @@ public interface CommonAPI {
      * @param key
      * @return
      */
-    String translateDictFromTable(String table, String text, String code, String key);
+    String translateDictFromTable(String table, String text, String code, String key,String extendsKey,String extendsValue);
 
     /**
      * 7普通字典的翻译
@@ -62,7 +62,7 @@ public interface CommonAPI {
      * @param key
      * @return
      */
-    String translateDict(String code, String key);
+    String translateDict(String code, String key,String extendsKey,String extendsValue);
 
     /**
      * 8查询数据权限

+ 21 - 13
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/DictAspect.java

@@ -14,17 +14,18 @@ import org.jeecg.common.api.CommonAPI;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.Dict;
 import org.jeecg.common.constant.CommonConstant;
-import org.jeecg.modules.base.service.BaseCommonService;
 import org.jeecg.common.util.oConvertUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
+
 import java.lang.reflect.Field;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
+
 /**
  * @Description: 字典aop类
  * @Author: dangzhenghui
@@ -35,18 +36,19 @@ import java.util.List;
 @Component
 @Slf4j
 public class DictAspect {
-
     @Autowired
     private CommonAPI commonAPI;
 
-    // 定义切点Pointcut
-    @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))")
+    /**
+     * 定义切点Pointcut
+     */
+    @Pointcut("execution(public * org.jeecg.modules..*.*Controller.*(..))||execution(public * cn.com.ctop..*.*Controller.*(..))")
     public void excudeService() {
     }
 
     @Around("excudeService()")
     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
-    	long time1=System.currentTimeMillis();	
+        long time1 = System.currentTimeMillis();
         Object result = pjp.proceed();
         long time2=System.currentTimeMillis();
         log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms");
@@ -101,17 +103,24 @@ public class DictAspect {
                             String code = field.getAnnotation(Dict.class).dicCode();
                             String text = field.getAnnotation(Dict.class).dicText();
                             String table = field.getAnnotation(Dict.class).dictTable();
+                            String extendsKey = field.getAnnotation(Dict.class).extendsKey();
+                            if("".equals(extendsKey.trim())){
+                                extendsKey = null;
+                            }
+                            String extendsValue = field.getAnnotation(Dict.class).extendsValue();
+                            if("".equals(extendsValue.trim())){
+                                extendsValue = null;
+                            }
                             String key = String.valueOf(item.get(field.getName()));
-
                             //翻译字典值对应的txt
-                            String textValue = translateDictValue(code, text, table, key);
+                            String textValue = translateDictValue(code, text, table, key,extendsKey,extendsValue);
 
                             log.debug(" 字典Val : "+ textValue);
                             log.debug(" __翻译字典字段__ "+field.getName() + CommonConstant.DICT_TEXT_SUFFIX+": "+ textValue);
                             item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
                         }
                         //date类型默认转换string格式化日期
-                        if (field.getType().getName().equals("java.util.Date")&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
+                        if ("java.util.Date".equals(field.getType().getName()) && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) {
                             SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                             item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
                         }
@@ -132,7 +141,7 @@ public class DictAspect {
      * @param key
      * @return
      */
-    private String translateDictValue(String code, String text, String table, String key) {
+    private String translateDictValue(String code, String text, String table, String key,String extendsKey,String extendsValue) {
     	if(oConvertUtils.isEmpty(key)) {
     		return null;
     	}
@@ -145,11 +154,11 @@ public class DictAspect {
                 continue; //跳过循环
             }
             if (!StringUtils.isEmpty(table)){
-                log.debug("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
-                tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim());
+                tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim(),extendsKey,extendsValue);
             }else {
-                tmpValue = commonAPI.translateDict(code, k.trim());
+                tmpValue = commonAPI.translateDict(code, k.trim(),extendsKey,extendsValue);
             }
+
             if (tmpValue != null) {
                 if (!"".equals(textValue.toString())) {
                     textValue.append(",");
@@ -160,5 +169,4 @@ public class DictAspect {
         }
         return textValue.toString();
     }
-
 }

+ 18 - 0
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/annotation/Dict.java

@@ -39,4 +39,22 @@ public @interface Dict {
      * @return 返回类型: String
      */
     String dictTable() default "";
+
+    /**
+     * 方法描述: 数据字典表
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String extendsKey() default "";
+
+    /**
+     * 方法描述: 数据字典表
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String extendsValue() default "";
 }

+ 27 - 37
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java

@@ -1,5 +1,7 @@
 package org.jeecg.common.util;
 
+import org.springframework.util.StringUtils;
+
 import java.beans.PropertyEditorSupport;
 import java.sql.Timestamp;
 import java.text.DateFormat;
@@ -9,14 +11,12 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 
-import org.springframework.util.StringUtils;
-
 /**
  * 类描述:时间操作定义类
  *
- * @Author: 张代浩
- * @Date:2012-12-8 12:15:03
- * @Version 1.0
+ * @author  张代浩
+ * 2012-12-8 12:15:03
+ * @version 1.0
  */
 public class DateUtils extends PropertyEditorSupport {
 
@@ -101,13 +101,11 @@ public class DateUtils extends PropertyEditorSupport {
     // 各种方式获取的Date
     // ////////////////////////////////////////////////////////////////////////////
 
-    /**
-     * 当前日期
-     *
-     * @return 系统当前时间
-     */
-    public static Date getDate() {
-        return new Date();
+    public static Date addSecond(Date date, int seconds) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.SECOND, seconds);
+        return calendar.getTime();
     }
 
     /**
@@ -123,8 +121,8 @@ public class DateUtils extends PropertyEditorSupport {
     /**
      * 时间戳转换为字符串
      *
-     * @param time
-     * @return
+     * @param time 时间戳
+     * @return 字符串
      */
     public static String timestamptoStr(Timestamp time) {
         Date date = null;
@@ -137,8 +135,8 @@ public class DateUtils extends PropertyEditorSupport {
     /**
      * 字符串转换时间戳
      *
-     * @param str
-     * @return
+     * @param str 字符串
+     * @return 时间戳
      */
     public static Timestamp str2Timestamp(String str) {
         Date date = str2Date(str, date_sdf.get());
@@ -148,9 +146,9 @@ public class DateUtils extends PropertyEditorSupport {
     /**
      * 字符串转换成日期
      *
-     * @param str
-     * @param sdf
-     * @return
+     * @param str 字符串
+     * @param sdf 格式
+     * @return 日期
      */
     public static Date str2Date(String str, SimpleDateFormat sdf) {
         if (null == str || "".equals(str)) {
@@ -173,19 +171,16 @@ public class DateUtils extends PropertyEditorSupport {
      * @return 字符串
      */
     public static String date2Str(SimpleDateFormat date_sdf) {
-        Date date = getDate();
-        if (null == date) {
-            return null;
-        }
+        Date date = new Date();
         return date_sdf.format(date);
     }
 
     /**
      * 格式化时间
      *
-     * @param date
-     * @param format
-     * @return
+     * @param date 日期
+     * @param format 格式
+     * @return 字符串
      */
     public static String dateformat(String date, String format) {
         SimpleDateFormat sformat = new SimpleDateFormat(format);
@@ -221,9 +216,6 @@ public class DateUtils extends PropertyEditorSupport {
      */
     public static String getDate(String format) {
         Date date = new Date();
-        if (null == date) {
-            return null;
-        }
         SimpleDateFormat sdf = new SimpleDateFormat(format);
         return sdf.format(date);
     }
@@ -283,7 +275,6 @@ public class DateUtils extends PropertyEditorSupport {
      * @return 指定日历的时间戳
      */
     public static Timestamp getCalendarTimestamp(Calendar cal) {
-        // ---------------------return new Timestamp(cal.getTimeInMillis());
         return new Timestamp(cal.getTime().getTime());
     }
 
@@ -291,8 +282,7 @@ public class DateUtils extends PropertyEditorSupport {
         Date dt = new Date();
         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String nowTime = df.format(dt);
-        java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
-        return buydate;
+        return java.sql.Timestamp.valueOf(nowTime);
     }
 
     // ////////////////////////////////////////////////////////////////////////////
@@ -533,7 +523,7 @@ public class DateUtils extends PropertyEditorSupport {
      * @param src     将要转换的原始字符窜
      * @param pattern 转换的匹配格式
      * @return 如果转换成功则返回转换后的日期
-     * @throws ParseException
+     * @throws ParseException 转化异常
      */
     public static Date parseDate(String src, String pattern) throws ParseException {
         return getSDFormat(pattern).parse(src);
@@ -546,7 +536,7 @@ public class DateUtils extends PropertyEditorSupport {
      * @param src     将要转换的原始字符窜
      * @param pattern 转换的匹配格式
      * @return 如果转换成功则返回转换后的日期
-     * @throws ParseException
+     * @throws ParseException 转化异常
      */
     public static Calendar parseCalendar(String src, String pattern) throws ParseException {
 
@@ -569,7 +559,7 @@ public class DateUtils extends PropertyEditorSupport {
      * @param src     将要转换的原始字符窜
      * @param pattern 转换的匹配格式
      * @return 如果转换成功则返回转换后的时间戳
-     * @throws ParseException
+     * @throws ParseException 转化异常
      */
     public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
         Date date = parseDate(src, pattern);
@@ -624,7 +614,7 @@ public class DateUtils extends PropertyEditorSupport {
     public void setAsText(String text) throws IllegalArgumentException {
         if (StringUtils.hasText(text)) {
             try {
-                if (text.indexOf(":") == -1 && text.length() == 10) {
+                if (!text.contains(":") && text.length() == 10) {
                     setValue(DateUtils.date_sdf.get().parse(text));
                 } else if (text.indexOf(":") > 0 && text.length() == 19) {
                     setValue(DateUtils.datetimeFormat.get().parse(text));
@@ -643,7 +633,7 @@ public class DateUtils extends PropertyEditorSupport {
 
     public static int getYear() {
         GregorianCalendar calendar = new GregorianCalendar();
-        calendar.setTime(getDate());
+        calendar.setTime(new Date());
         return calendar.get(Calendar.YEAR);
     }
 

+ 1 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceAdvertisePlan.java

@@ -10,7 +10,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import org.jeecg.common.aspect.annotation.Dict;
-import org.jeecg.modules.bytedance.advertise.utils.CtopAdConstant;
+import org.jeecg.modules.bytedance.common.utils.CtopAdConstant;
 
 import java.math.BigDecimal;
 import java.util.Date;

+ 1 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceCreative.java

@@ -8,6 +8,7 @@ import io.swagger.annotations.ApiModel;
 import lombok.Data;
 import lombok.experimental.Accessors;
 import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
 
 import java.util.Date;
 

+ 1 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceVideoInfo.java

@@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
 import org.jeecgframework.poi.excel.annotation.Excel;
 
 import java.util.Date;

+ 1 - 3
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceImageInfo.java

@@ -1,15 +1,13 @@
 package org.jeecg.modules.bytedance.advertise.entity;
 
-import cn.com.ctop.common.module.entity.CtopOauthToken;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
-import org.jeecgframework.poi.excel.annotation.Excel;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
 
 import java.util.Date;
 

+ 21 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceAdvertisePlanMapper.java

@@ -0,0 +1,21 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import io.lettuce.core.dynamic.annotation.Param;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @Description: 今日头条广告计划信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceAdvertisePlanMapper extends BaseMapper<ByteDanceAdvertisePlan> {
+
+    List<String> selectWarningGroup(@Param("accountId") Long accountId, @Param("maxBid") BigDecimal maxBid);
+
+    List<String> selectWarningCpaBid(@Param("accountId") Long accountId, @Param("maxCpaBid") BigDecimal maxCpaBid);
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceAdvertiserMapper.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertiser;
+
+/**
+ * @Description: 今日头条广告主信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceAdvertiserMapper extends BaseMapper<ByteDanceAdvertiser> {
+
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceAudiencePackageMapper.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAudiencePackage;
+
+/**
+ * 头条定向包
+ * @author: jeecg-boot
+ * @date:   2020-07-22
+ * @cersion: V1.0
+ */
+public interface ByteDanceAudiencePackageMapper extends BaseMapper<ByteDanceAudiencePackage> {
+
+}

+ 17 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceCampaignMapper.java

@@ -0,0 +1,17 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCampaign;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条广告组信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceCampaignMapper extends BaseMapper<ByteDanceCampaign> {
+    void replaceBatch(@Param(value = "campaigns") List<ByteDanceCampaign> campaigns);
+}

+ 18 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceCreativeMapper.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreative;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条创意信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceCreativeMapper extends BaseMapper<ByteDanceCreative> {
+
+    void replaceBatch(@Param(value = "creatives") List<ByteDanceCreative> creatives);
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceCreativeMaterialMapper.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreativeMaterial;
+
+/**
+ * @Description: 今日头条创意素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface ByteDanceCreativeMaterialMapper extends BaseMapper<ByteDanceCreativeMaterial> {
+
+}

+ 21 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceVideoInfoMapper.java

@@ -0,0 +1,21 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条视频素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+public interface ByteDanceVideoInfoMapper extends BaseMapper<ByteDanceVideoInfo> {
+
+    void replaceBatch(@Param(value = "videoList") List<ByteDanceVideoInfo> videoInfoList);
+
+    void updateVideoVerticalType();
+    void updateVideoHorizonType();
+}

+ 22 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/BytedanceImageInfoMapper.java

@@ -0,0 +1,22 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.bytedance.advertise.entity.BytedanceImageInfo;
+
+import java.util.List;
+
+/**
+ * 头条图片素材
+ * @author: jeecg-boot
+ * @date:   2020-08-01
+ * @cersion: V1.0
+ */
+public interface BytedanceImageInfoMapper extends BaseMapper<BytedanceImageInfo> {
+
+    void replaceBatch(@Param(value = "imageInfos")List<BytedanceImageInfo> imageInfos);
+
+    void updateImageVerticalType();
+
+    void updateImageHorizonType();
+}

+ 25 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceAdvertisePlanMapper.xml

@@ -0,0 +1,25 @@
+<?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="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceAdvertisePlanMapper">
+
+    <select id="selectWarningGroup" resultType="java.lang.String">
+   SELECT
+   name
+   FROM ctop_bytedance_advertise_plan
+   WHERE account_id = #{accountId}
+   and (cpa_bid &gt; #{maxBid} or bid &gt; #{maxBid})
+   and toutiao_status = 'AD_STATUS_DELIVERY_OK'
+    </select>
+
+
+    <select id="selectWarningCpaBid" resultType="java.lang.String">
+   SELECT
+   name
+   FROM ctop_bytedance_advertise_plan
+   WHERE account_id = #{accountId}
+   and deep_cpabid &gt; #{maxCpaBid}
+   and toutiao_status = 'AD_STATUS_DELIVERY_OK'
+    </select>
+
+
+</mapper>

+ 5 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceAdvertiserMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceAdvertiserMapper">
+
+</mapper>

+ 5 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceAudiencePackageMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceAudiencePackageMapper">
+
+</mapper>

+ 37 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceCampaignMapper.xml

@@ -0,0 +1,37 @@
+<?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="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCampaignMapper">
+
+    <insert id="replaceBatch">
+        replace into ctop_bytedance_campaign(
+        id,
+        account_id,
+        name,
+        budget,
+        budget_mode,
+        landing_type,
+        modify_time,
+        status,
+        campaign_create_time,
+        campaign_modify_time,
+        create_time,
+        update_time)
+        values
+        <foreach collection="campaigns" item="report" separator=",">
+            (
+            #{report.id},
+            #{report.accountId},
+            #{report.name},
+            #{report.budget},
+            #{report.budgetMode},
+            #{report.landingType},
+            #{report.modifyTime},
+            #{report.status},
+            #{report.campaignCreateTime},
+            #{report.campaignModifyTime},
+            #{report.createTime},
+            #{report.updateTime}
+            )
+        </foreach>
+    </insert>
+</mapper>

+ 48 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceCreativeMapper.xml

@@ -0,0 +1,48 @@
+<?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="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCreativeMapper">
+    <insert id="replaceBatch">
+        replace into ctop_bytedance_creative(
+        id,
+        plan_id,
+        toutiao_id,
+        account_id,
+        title,
+        creative_word_ids,
+        status,
+        opt_status,
+        image_mode,
+        image_ids,
+        image_id,
+        video_id,
+        audit_reject_reason,
+        third_party_id,
+        creative_create_time,
+        creative_modify_time,
+        create_time,
+        update_time)
+        values
+        <foreach collection="creatives" item="report" separator=",">
+            (
+            #{report.id},
+            #{report.planId},
+            #{report.toutiaoId},
+            #{report.accountId},
+            #{report.title},
+            #{report.creativeWordIds},
+            #{report.status},
+            #{report.optStatus},
+            #{report.imageMode},
+            #{report.imageIds},
+            #{report.imageId},
+            #{report.videoId},
+            #{report.auditRejectReason},
+            #{report.thirdPartyId},
+            #{report.creativeCreateTime},
+            #{report.creativeModifyTime},
+            #{report.createTime},
+            #{report.updateTime}
+            )
+        </foreach>
+    </insert>
+</mapper>

+ 5 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceCreativeMaterialMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCreativeMaterialMapper">
+
+</mapper>

+ 69 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceVideoInfoMapper.xml

@@ -0,0 +1,69 @@
+<?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="org.jeecg.modules.bytedance.advertise.mapper.ByteDanceVideoInfoMapper">
+    <insert id="replaceBatch">
+        replace into ctop_bytedance_video_info(
+        id,
+        vid,
+        advertiser_id,
+        account_id,
+        material_id,
+        url,
+        material_upload_time,
+        filename,
+        format,
+        poster_url,
+        bit_rate,
+        source,
+        file_id,
+        width,
+        height,
+        duration,
+        size,
+        video_url,
+        status,
+        create_time,
+        update_time,
+        signature)
+        values
+        <foreach collection="videoList" item="video" separator=",">
+            (
+            #{video.id},
+            #{video.vid},
+            #{video.advertiserId},
+            #{video.accountId},
+            #{video.materialId},
+            #{video.url},
+            #{video.materialUploadTime},
+            #{video.filename},
+            #{video.format},
+            #{video.posterUrl},
+            #{video.bitRate},
+            #{video.source},
+            #{video.fileId},
+            #{video.width},
+            #{video.height},
+            #{video.duration},
+            #{video.size},
+            #{video.videoUrl},
+            #{video.status},
+            #{video.createTime},
+            #{video.updateTime},
+            #{video.signature}
+            )
+        </foreach>
+    </insert>
+    <update id="updateVideoVerticalType">
+        update
+            ctop_bytedance_video_info
+        set type = 2
+        where height &gt; width and type is null
+        and (height between 1280 and 2560)  and (width between 720 and 1440)
+    </update>
+    <update id="updateVideoHorizonType">
+        update ctop_bytedance_video_info
+            set type = 1
+        where height &lt; width and type is null
+        and (width between 1280 and 2560)  and (height between 720 and 1440)
+    </update>
+</mapper>

+ 49 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/BytedanceImageInfoMapper.xml

@@ -0,0 +1,49 @@
+<?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="org.jeecg.modules.bytedance.advertise.mapper.BytedanceImageInfoMapper">
+
+    <insert id="replaceBatch">
+        replace into ctop_bytedance_image_info(
+        id,
+        account_id,
+        material_id,
+        size,
+        width,
+        height,
+        url,
+        format,
+        signature,
+        image_create_time,
+        create_time,
+        update_time,image_url)
+        values
+        <foreach collection="imageInfos" item="imageInfo" separator=",">
+            (#{imageInfo.id},
+            #{imageInfo.accountId},
+            #{imageInfo.materialId},
+            #{imageInfo.size},
+            #{imageInfo.width},
+            #{imageInfo.height},
+            #{imageInfo.url},
+            #{imageInfo.format},
+            #{imageInfo.signature},
+            #{imageInfo.imageCreateTime},
+            #{imageInfo.createTime},
+            #{imageInfo.updateTime},#{imageInfo.imageUrl})
+        </foreach>
+    </insert>
+
+    <update id="updateImageVerticalType">
+        update
+            ctop_bytedance_image_info
+        set type = 2
+        where height &gt; width and type is null
+        and (height between 1280 and 2560)  and (width between 720 and 1440);
+    </update>
+    <update id="updateImageHorizonType">
+        update ctop_bytedance_image_info
+            set type = 1
+        where height &lt; width and type is null
+        and (width between 1280 and 2560)  and (height between 720 and 1440)
+    </update>
+</mapper>

+ 48 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertisePlanService.java

@@ -0,0 +1,48 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 今日头条广告计划信息
+ * @author jeecg-boot
+ * 2019-07-22
+ * @version V1.0
+ */
+public interface IByteDanceAdvertisePlanService extends IService<ByteDanceAdvertisePlan> {
+
+    //获取广告计划  https://ad.oceanengine.com/open_api/2/ad/get/
+    Map<String, Object> getAdvertiserPlan(CtopOauthToken token, String ids, String date, String updateDate);
+
+    //创建广告计划  https://ad.oceanengine.com/open_api/2/ad/create/
+    Map<String, Object> createAdvertiserPlan(CtopOauthToken token, String landingType, ByteDanceAdvertisePlan byteDanceAdvertisePlan);
+
+    //修改广告计划  https://ad.oceanengine.com/open_api/2/ad/update/
+    Map<String, Object> updateAdvertiserPlan(CtopOauthToken token,String landingType, ByteDanceAdvertisePlan byteDanceAdvertisePlan);
+
+    //更新计划状态  https://ad.oceanengine.com/open_api/2/ad/update/status/
+    Map<String, Object> updateAdvertiserPlanStatus(CtopOauthToken token, JSONArray adIds, String optStatus);
+
+    //更新计划预算  https://ad.oceanengine.com/open_api/2/ad/update/budget/
+    Map<String, Object> updateAdvertiserPlanBudget(CtopOauthToken token, JSONArray adIds, JSONArray budgets);
+
+    //更新计划出价  https://ad.oceanengine.com/open_api/2/ad/update/bid/
+    Map<String, Object> updateAdvertiserPlanBid(CtopOauthToken token, JSONArray adIds,JSONArray bids);
+
+    //获取计划审核建议  https://ad.oceanengine.com/open_api/2/ad/reject_reason/
+    Map<String, Object> getAdvertiserPlanRejectReason(CtopOauthToken token, Long advertiserId, List<Long> adIds);
+
+    //查询需要预警的广告计划名称
+    List<String> selectWarningGroup(Long accountId, BigDecimal maxBid);
+
+    //查询需要预警的深度转化出价
+    List<String> selectWarningCpaBid(Long accountId, BigDecimal maxCapBid);
+
+    List<ByteDanceAdvertisePlan> getAllPlans(Long accountId,String createDate);
+}

+ 48 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertiserDataService.java

@@ -0,0 +1,48 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+
+import java.util.Map;
+
+/**
+ * @author jeecg-boot
+ */
+public interface IByteDanceAdvertiserDataService {
+
+    JSONObject getAdvertiserList(String token, Long accountId);
+
+    Map<String, Object> getAdvertiserInfo(String accountId, String token);
+
+    ByteDanceAdvertisePlan getSinglePlanById(CtopOauthToken token, String id);
+
+    Map<String, Object> getAdvertiserPlan(CtopOauthToken token, String ids, String date, String updateDate);
+
+    Map<String, Object> getAdvertiserBudget(String accountId);
+
+    Map<String, Object> getAdvertiserCreativeMaterial(String accountId, String creativeIds);
+
+    Map<String, Object> advertiserPlanUpdateStatus(CtopOauthToken token, String adIds, String optStatus);
+
+    Map<String, Object> advertiserPlanUpdateBid(CtopOauthToken token, String adIds, String bids);
+
+    Map<String, Object> advertiserPlanUpdateBudget(CtopOauthToken token, String adIds, String budgets);
+
+    Map<String, Object> advertiserCustomAudienceSelect(String accountId);
+
+    Map<String, Object> getAdvertiserCampaignList(String accountId);
+
+    Map<String, Object> flowPackageGet(String accountId);
+
+    void getMaterialList(CtopOauthToken token);
+
+    void getImageByPage(CtopOauthToken token, String imageIds, int page);
+
+    JSONArray advertiserList(String token);
+
+
+    void getBytedancePlanList(String accountId, String accessToken, int pageNum, String createDate, String updateDate);
+
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertiserService.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertiser;
+
+/**
+ * 今日头条广告主信息
+ * @author jeecg-boot
+ * 2019-07-22
+ * @version V1.0
+ */
+public interface IByteDanceAdvertiserService extends IService<ByteDanceAdvertiser> {
+
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAudiencePackageService.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAudiencePackage;
+
+/**
+ * 头条定向包
+ * @author jeecg-boot
+ * @date   2020-07-22
+ * @version V1.0
+ */
+public interface IByteDanceAudiencePackageService extends IService<ByteDanceAudiencePackage> {
+
+}

+ 22 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCampaignService.java

@@ -0,0 +1,22 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCampaign;
+import org.jeecg.modules.bytedance.advertise.vo.BytedanceCampaignEditVo;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+
+import java.util.Map;
+
+/**
+ * @Description: 今日头条广告组信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface IByteDanceCampaignService extends IService<ByteDanceCampaign> {
+    Map<String,Object> createCampaign(Long accountId, String campaignName, String operation, String budgetMode, String budget, String landingType, String uniqueFk);
+    Map<String,Object>updateCampaign(CtopOauthToken token, Long campaignId, String campaignName, String modifyTime, Integer budget);
+    Map<String, Object> updateCampaignStatus(Long accountId, String campaignIds, String optStatus);
+    Map<String, Object> getAdvertiserCampaign(CtopOauthToken token, String ids, String date);
+    Map<String, Object> updateCampaign(BytedanceCampaignEditVo editVo);
+}

+ 14 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCreativeMaterialService.java

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreativeMaterial;
+
+/**
+ * @Description: 今日头条创意素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface IByteDanceCreativeMaterialService extends IService<ByteDanceCreativeMaterial> {
+
+}

+ 34 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCreativeService.java

@@ -0,0 +1,34 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreative;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 今日头条创意信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+public interface IByteDanceCreativeService extends IService<ByteDanceCreative> {
+
+    Map<String, Object> creativeCreate(String accountId, Long campaignId, JSONObject data);
+
+    Map<String, Object> getAdvertiserCreative(CtopOauthToken token, String ids, String date);
+
+    Map<String, Object> advertiserCreativeUpdateStatus(CtopOauthToken cTopOauthToken,Long accountId, String creativeIds, String optStatus);
+
+    void replaceBatch(List<ByteDanceCreative> creatives);
+
+    Map<String, Object> getCreativeDetail(CtopOauthToken token, Long planId);
+
+    Map<String,Object> updateCreative(JSONObject data);
+
+    Map<String,Object> getCreativeRejectReason(Long accountId, Long creativeId);
+
+    Map<String, Object> batchCreate(JSONObject data);
+}

+ 21 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceVideoInfoService.java

@@ -0,0 +1,21 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条视频素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+public interface IByteDanceVideoInfoService extends IService<ByteDanceVideoInfo> {
+
+    void replaceBatch(List<ByteDanceVideoInfo> videoInfoList);
+
+    ByteDanceVideoInfo getOneByParams(Long materialId);
+
+    void updateMaterialType();
+}

+ 5 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IBytedanceBidWarningService.java

@@ -0,0 +1,5 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+public interface IBytedanceBidWarningService {
+    void bidWarning();
+}

+ 18 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IBytedanceImageInfoService.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.BytedanceImageInfo;
+
+import java.util.List;
+
+/**
+ * 头条图片素材
+ * @author jeecg-boot
+ * @date   2020-08-01
+ * @version V1.0
+ */
+public interface IBytedanceImageInfoService extends IService<BytedanceImageInfo> {
+    void replaceBatch(List<BytedanceImageInfo> videoInfoList);
+
+    void updateType();
+}

+ 470 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertisePlanServiceImpl.java

@@ -0,0 +1,470 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceAdvertisePlanMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAdvertisePlanService;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.utils.HttpUtils;
+import org.jeecg.modules.bytedance.common.utils.PropertiesUtils;
+import org.jeecg.modules.bytedance.common.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class ByteDanceAdvertisePlanServiceImpl extends ServiceImpl<ByteDanceAdvertisePlanMapper, ByteDanceAdvertisePlan> implements IByteDanceAdvertisePlanService {
+    @Autowired
+    private ByteDanceAdvertisePlanMapper byteDanceAdvertisePlanMapper;
+    @Override
+    public Map<String, Object> getAdvertiserPlan(CtopOauthToken token, String ids, String date, String updateDate) {
+        getAd(token, 1, ids, date, updateDate);
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告计划信息成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> createAdvertiserPlan(CtopOauthToken token, String landingType, ByteDanceAdvertisePlan byteDanceAdvertisePlan) {
+
+        Map<String, Object> resultMap = new HashMap<>();
+        //拼接访问参数
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", byteDanceAdvertisePlan.getAccountId());
+        params.put("campaign_id", byteDanceAdvertisePlan.getCampaignId());
+        params.put("name", byteDanceAdvertisePlan.getName());
+        params.put("operation", byteDanceAdvertisePlan.getOperation() == null ? "enable" : byteDanceAdvertisePlan.getOperation());
+        params.put("delivery_range", byteDanceAdvertisePlan.getDeliveryRange() == null ? "DEFAULT" : byteDanceAdvertisePlan.getDeliveryRange());
+        params.put("union_video_type", byteDanceAdvertisePlan.getUnionVideoType() == null ? "ORIGINAL_VIDEO" : byteDanceAdvertisePlan.getUnionVideoType());
+        params.put("budget_mode", byteDanceAdvertisePlan.getBudgetMode());
+        params.put("budget", byteDanceAdvertisePlan.getBudget());
+        params.put("schedule_type", byteDanceAdvertisePlan.getScheduleType());
+        params.put("start_time", byteDanceAdvertisePlan.getStartTime());
+        params.put("end_time", byteDanceAdvertisePlan.getEndTime());
+        //广告投放时段
+        if(!"".equals(byteDanceAdvertisePlan.getScheduleTime())){
+            params.put("schedule_time",byteDanceAdvertisePlan.getScheduleTime());
+        }
+        params.put("pricing", byteDanceAdvertisePlan.getPricing());
+        params.put("bid", byteDanceAdvertisePlan.getBid());
+        params.put("cpa_bid", byteDanceAdvertisePlan.getCpaBid());
+        params.put("flow_control_mode", byteDanceAdvertisePlan.getFlowControlMode());
+        if ("PRICING_OCPM".equals(byteDanceAdvertisePlan.getPricing())) {
+            if(byteDanceAdvertisePlan.getConvertId()!=null){
+                //查询必填参数convert_id
+                params.put("convert_id", byteDanceAdvertisePlan.getConvertId());
+            }else{
+                int convertId=getConvertIdByExternalAction(byteDanceAdvertisePlan.getExternalAction());
+                params.put("convert_id",convertId);
+                byteDanceAdvertisePlan.setConvertId((long) convertId);
+            }
+        }
+        params.put("deep_bid_type", byteDanceAdvertisePlan.getDeepBidType());
+        params.put("deep_cpabid", byteDanceAdvertisePlan.getDeepCpaBid());
+        params.put("hide_if_converted", byteDanceAdvertisePlan.getHideIfConverted());
+        params.put("hide_if_exists", byteDanceAdvertisePlan.getHideIfExists() == null ? 0 : byteDanceAdvertisePlan.getHideIfExists());
+        params.put("converted_time_duration", byteDanceAdvertisePlan.getConvertedTimeDuration());
+        params.put("luban_roi_goal",byteDanceAdvertisePlan.getLubanRoiGoal());
+        params.put("roi_goal",byteDanceAdvertisePlan.getRoiGoal());
+        //params.put("unique_fk",byteDanceAdvertisePlan.getUniqueFk")==null?"":byteDanceAdvertisePlan.getString("uniqueFk"));
+        //params.put("smart_bid_type",byteDanceAdvertisePlan.getSmartBidType")==null?"":byteDanceAdvertisePlan.getString("smartBidType"));
+        params.put("adjust_cpa", 0);
+        //暂时不需要定向包id
+        //params.put("audience_package_id",byteDanceAdvertisePlan.getLong("audiencePackageId"));
+        if("YES".equals(byteDanceAdvertisePlan.getUseOpenUrl())){
+            params.put("open_url", byteDanceAdvertisePlan.getOpenUrl());
+        }
+        //判断推广目的
+        if ("LINK".equals(landingType)) {
+            params.put("external_url", byteDanceAdvertisePlan.getExternalUrl());
+        }
+        if ("APP".equals(landingType)) {
+            params.put("download_type", byteDanceAdvertisePlan.getDownloadType());
+            params.put("download_url", byteDanceAdvertisePlan.getDownloadUrl());
+            params.put("package", byteDanceAdvertisePlan.getToutiaoPackage());
+            params.put("app_type",byteDanceAdvertisePlan.getAppType());
+        }
+
+        //公共参数--受众相关
+        params.put("retargeting_tags_include", byteDanceAdvertisePlan.getRetargetingTags());
+        params.put("retargeting_tags_exclude", byteDanceAdvertisePlan.getRetargetingTagsExclude());
+        params.put("gender", byteDanceAdvertisePlan.getGender());
+        params.put("age", byteDanceAdvertisePlan.getAge());
+        params.put("carrier", byteDanceAdvertisePlan.getCarrier());
+        params.put("ac", byteDanceAdvertisePlan.getAc());
+        params.put("device_brand", byteDanceAdvertisePlan.getDeviceBrand());
+        params.put("article_category", byteDanceAdvertisePlan.getArticleCategory());
+        params.put("activate_type", byteDanceAdvertisePlan.getActivateType());
+        params.put("city", byteDanceAdvertisePlan.getCity());
+        params.put("business_ids", byteDanceAdvertisePlan.getBusinessIds());
+        params.put("location_type", byteDanceAdvertisePlan.getLocationType());
+        params.put("superior_popularity_type", byteDanceAdvertisePlan.getSuperiorPopularityType());
+        params.put("flow_package", byteDanceAdvertisePlan.getFlowPackage());
+        params.put("exclude_flow_package", byteDanceAdvertisePlan.getExcludeFlowPackage());
+        params.put("device_type", byteDanceAdvertisePlan.getDeviceType());
+        params.put("auto_extend_enabled", byteDanceAdvertisePlan.getAutoExtendEnabled());
+        params.put("launch_price", byteDanceAdvertisePlan.getLaunchPrice());
+        params.put("interest_action_mode", byteDanceAdvertisePlan.getInterestActionMode());
+        params.put("action_scene", byteDanceAdvertisePlan.getActionScene());
+        params.put("action_days", byteDanceAdvertisePlan.getActionDays());
+        params.put("action_categories", byteDanceAdvertisePlan.getActionCategories());
+        params.put("action_words", byteDanceAdvertisePlan.getActionWords());
+        params.put("interest_categories", byteDanceAdvertisePlan.getInterestWords());
+        params.put("interest_words", byteDanceAdvertisePlan.getGeolocation());
+
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_create"), params, headers));
+        if (jsonObject.getInteger("code") == 0) {
+            resultMap.put("code", 0);
+            byteDanceAdvertisePlan.setId(jsonObject.getJSONObject("data").getLong("ad_id"));
+            resultMap.put("data",byteDanceAdvertisePlan);
+        } else {
+            log.error("广告计划创建失败==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code",-200);
+            resultMap.put("message", jsonObject.getString("message"));
+        }
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> updateAdvertiserPlan(CtopOauthToken token, String landingType, ByteDanceAdvertisePlan byteDanceAdvertisePlan) {
+
+        Map<String, Object> resultMap = new HashMap<>();
+
+        //查询记录,获取修改时间等字段
+        List adId=new ArrayList();
+        adId.add(byteDanceAdvertisePlan.getId());
+        Map<String, Object> map = queryAdByAdId(token, Long.valueOf(byteDanceAdvertisePlan.getAccountId()), adId);
+        if(!map.get("code").equals(0)){
+            log.error("获取修改时间接口错误");
+        }else {
+            Object modifyTime = ((Map) ((JSONObject) map.get("data")).getJSONArray("list").get(0)).get("modify_time");
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Content-Type", "application/json");
+            headers.put("Access-Token", token.getAccessToken());
+
+            JSONObject params = new JSONObject();
+            params.put("advertiser_id", byteDanceAdvertisePlan.getAccountId());
+            params.put("ad_id", byteDanceAdvertisePlan.getId());
+            params.put("name", byteDanceAdvertisePlan.getName());
+            params.put("modify_time", modifyTime);
+            params.put("budget", byteDanceAdvertisePlan.getBudget());
+            params.put("schedule_type", byteDanceAdvertisePlan.getScheduleType());
+            params.put("start_time", byteDanceAdvertisePlan.getStartTime());
+            params.put("end_time", byteDanceAdvertisePlan.getEndTime());
+            //广告投放时段
+            if(!"".equals(byteDanceAdvertisePlan.getScheduleTime())){
+                params.put("schedule_time",byteDanceAdvertisePlan.getScheduleTime());
+            }
+            params.put("bid", byteDanceAdvertisePlan.getBid());
+            params.put("cpa_bid", byteDanceAdvertisePlan.getCpaBid());
+            params.put("flow_control_mode", byteDanceAdvertisePlan.getFlowControlMode());
+            params.put("convert_id", byteDanceAdvertisePlan.getConvertId());
+            params.put("deep_bid_type", byteDanceAdvertisePlan.getDeepBidType());
+            params.put("deep_cpabid", byteDanceAdvertisePlan.getDeepCpaBid());
+            params.put("hide_if_converted", byteDanceAdvertisePlan.getHideIfConverted());
+            params.put("hide_if_exists", byteDanceAdvertisePlan.getHideIfExists() == null ? 0 : byteDanceAdvertisePlan.getHideIfExists());
+            //params.put("converted_time_duration", byteDanceAdvertisePlan.getConvertedTimeDuration());
+            //params.put("luban_roi_goal",byteDanceAdvertisePlan.getLubanRoiGoal()==null?0.00:byteDanceAdvertisePlan.getFloat("lubanRoiGoal"));
+            //params.put("roi_goal",byteDanceAdvertisePlan.getFroiGoal")==null?0.00:byteDanceAdvertisePlan.getFloat("roiGoal"));
+            //params.put("audience_package_id",byteDanceAdvertisePlan.getLong("audiencePackageId"));
+            params.put("adjust_cpa", 0);
+            //暂时不需要定向包id
+            //params.put("audience_package_id",byteDanceAdvertisePlan.getLong("audiencePackageId"));
+        /*if(byteDanceAdvertisePlan.getUseOpenUrl().equals("YES")){
+            params.put("open_url", byteDanceAdvertisePlan.getOpenUrl());
+        }*/
+            //判断推广目的
+        /*if (landingType.equals("LINK")) {
+            params.put("external_url", byteDanceAdvertisePlan.getExternalUrl());
+        }
+        if (landingType.equals("APP")) {
+            params.put("download_type", byteDanceAdvertisePlan.getDownloadType());
+            params.put("download_url", byteDanceAdvertisePlan.getDownloadUrl());
+            params.put("package", byteDanceAdvertisePlan.getToutiaoPackage());
+            params.put("app_type",byteDanceAdvertisePlan.getAppType());
+        }*/
+            JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update"), params, headers));
+            if (jsonObject.getInteger("code") != 0) {
+                log.error("广告计划修改失败==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+                resultMap.put("code", -1);
+                resultMap.put("message", jsonObject.getString("message"));
+                return resultMap;
+            }
+            resultMap.put("code", 0);
+            resultMap.put("message", "广告组状态修改成功");
+        }
+
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> updateAdvertiserPlanStatus(CtopOauthToken token, JSONArray adIds, String optStatus) {
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+        switch (optStatus) {
+            case "AD_STATUS_DISABLE":
+                optStatus = "disable";
+                break;
+            case "AD_STATUS_ENABLE":
+                optStatus = "enable";
+                break;
+            case "AD_STATUS_DELETE":
+                optStatus = "delete";
+                break;
+        }
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("ad_ids", adIds.toJSONString());
+        params.put("opt_status", optStatus);
+        String result = HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_status"), params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        int code = jsonObject.getInteger("code");
+        Map<String, Object> resultMap = new HashMap<>();
+        if (code != 0) {
+            log.error("广告计划更新状态接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", jsonObject.getString("message"));
+            return resultMap;
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告组状态修改成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> updateAdvertiserPlanBudget(CtopOauthToken token, JSONArray adIds, JSONArray budgets) {
+        JSONArray data = new JSONArray();
+        if (adIds.size() > 0) {
+            for (int i = 0; i < adIds.size(); i++) {
+                JSONObject object = new JSONObject();
+                Long adId = Long.valueOf(adIds.get(i).toString());
+                Long budget = Long.valueOf(budgets.get(i).toString());
+                object.put("ad_id", adId);
+                object.put("budget", budget);
+                data.add(object);
+            }
+        }
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("data", data.toJSONString());
+        String result = HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_budget"), params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Map<String, Object> resultMap = new HashMap<>();
+        int code = jsonObject.getInteger("code");
+        if (code!=0) {
+            log.info("修改计划预算接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", jsonObject.getString("message"));
+            return resultMap;
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "修改计划预算成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> updateAdvertiserPlanBid(CtopOauthToken token, JSONArray adIds, JSONArray bids) {
+        JSONArray data = new JSONArray();
+        if (adIds.size() > 0) {
+            for (int i = 0; i < adIds.size(); i++) {
+                JSONObject object = new JSONObject();
+                Long adId = Long.valueOf(adIds.get(i).toString());
+                Long bid = Long.valueOf(bids.get(i).toString());
+                object.put("ad_id", adId);
+                object.put("bid", bid);
+                data.add(object);
+            }
+        }
+        //2: 根据token以及用户id获取用户信息数据
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("data", data.toJSONString());
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_bid"), params, headers));
+        int code = jsonObject.getInteger("code");
+        Map<String, Object> resultMap = new HashMap<>();
+        if (code != 0) {
+            log.info("修改计划出价接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", jsonObject.getString("message"));
+            return resultMap;
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "修改计划出价成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserPlanRejectReason(CtopOauthToken token, Long advertiserId, List<Long> adIds) {
+
+        Map<String, Object> resultMap = new HashMap<>();
+
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_reject_reason");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", advertiserId);
+        params.put("ad_ids", adIds);
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        int code = jsonObject.getInteger("code");
+        if (code != 0) {
+            log.info("获取计划审核建议接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", jsonObject.getString("message"));
+            return resultMap;
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取计划审核建议成功");
+        return resultMap;
+    }
+
+
+    public void getAd(CtopOauthToken token, int pageNum, String ids, String date, String updateDate) {
+        JSONArray getIds = new JSONArray();
+        if (null != ids && !"".equals(ids)) {
+            String[] idString = ids.split(StringUtils.COMMA);
+            if (idString.length > 0) {
+                for (String s : idString) {
+                    Long getId = Long.parseLong(s);
+                    getIds.add(getId);
+                }
+            }
+        }
+        // 请求地址
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_get");
+        // 请求参数
+        Map<String, Object> filtering = new HashMap<>();
+        if (getIds.size() > 0) {
+            filtering.put("ids", getIds);
+        }
+        if (null != date && !"".equals(date)) {
+            filtering.put("ad_create_time", date);
+        }
+        if (null != updateDate && !"".equals(updateDate)) {
+            filtering.put("ad_modify_time", updateDate);
+        }
+
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", pageNum);
+        param.put("page_size", 100);
+        param.put("filtering", filtering);
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        int code = resultObject.getInteger("code");
+        if (code != 0) {
+            log.error("获取广告计划信息接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, String.valueOf(token.getAccountId()));
+            BigDecimal deepCpaBid = dataObject.getBigDecimal("deep_cpabid");
+            if (null != deepCpaBid) {
+                advertisePlan.setDeepCpaBid(deepCpaBid);
+            }
+            this.saveOrUpdate(advertisePlan);
+        }
+        getAd(token, pageNum + 1, ids, date, updateDate);
+    }
+
+    @Override
+    public List<String> selectWarningGroup(Long accountId, BigDecimal maxBid) {
+        return byteDanceAdvertisePlanMapper.selectWarningGroup(accountId, maxBid);
+
+    }
+
+    @Override
+    public List<String> selectWarningCpaBid(Long accountId, BigDecimal maxCapBid) {
+        return byteDanceAdvertisePlanMapper.selectWarningCpaBid(accountId, maxCapBid);
+    }
+
+    @Override
+    public List<ByteDanceAdvertisePlan> getAllPlans(Long accountId,String createDate) {
+        QueryWrapper<ByteDanceAdvertisePlan>queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id",accountId+"");
+        if(null!=createDate&&!"".equals(createDate.trim())){
+            queryWrapper.ge("ad_create_time",createDate+" 00:00:00");
+        }
+        queryWrapper.ne("opt_status","AD_STATUS_DELETE");
+        queryWrapper.orderByDesc("ad_create_time");
+        return this.list(queryWrapper);
+    }
+
+    private Map<String, Object> queryAdByAdId(CtopOauthToken token, Long accountId, List adId){
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", accountId);
+        Map<String, Object> filtering = new HashMap<>();
+        filtering.put("ids",adId);
+        params.put("filtering", filtering);
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpGetRequest(PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_get"), headers, params));
+        Map<String, Object> resultMap = new HashMap<>();
+        if (jsonObject.getInteger("code") == 0) {
+            resultMap.put("code", 0);
+            resultMap.put("data",jsonObject.getJSONObject("data"));
+        } else {
+            log.error("广告计划查询失败==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code",-200);
+            resultMap.put("message", jsonObject.getString("message"));
+        }
+        return resultMap;
+    }
+
+    private int getConvertIdByExternalAction(String externalAction){
+        int result=0;
+        switch (externalAction) {
+            case "AD_CONVERT_TYPE_DOWNLOAD_FINISH":
+                result = 4;
+                break;
+            case "AD_CONVERT_TYPE_BUTTON":
+                result = 5;
+                break;
+            case "AD_CONVERT_TYPE_DOWNLOAD_START":
+                result = 9;
+                break;
+            case "AD_CONVERT_TYPE_INSTALL_FINISH":
+                result = 15;
+                break;
+            case "AD_CONVERT_TYPE_REDIRECT":
+                result = 95;
+                break;
+        }
+        return result;
+    }
+
+}

+ 790 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertiserDataServiceImpl.java

@@ -0,0 +1,790 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.bytedance.advertise.entity.*;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCreativeMapper;
+import org.jeecg.modules.bytedance.advertise.service.*;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
+import org.jeecg.modules.bytedance.common.utils.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * @author 宋英豪
+ */
+@Slf4j
+@Service
+@Primary
+public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserDataService {
+    @Value("${bytedance.appId}")
+    private String bytedanceAppId;
+    @Value("${bytedance.secret}")
+    private String bytedanceSecret;
+    @Value("${bytedance.url.api-prefix}")
+    private String bytedanceApiUrl;
+    @Value("${bytedance.url.ad-get}")
+    private String bytedanceAdGetUrl;
+
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IByteDanceAdvertisePlanService advertisePlanService;
+    @Autowired
+    private IByteDanceCreativeMaterialService creativeMaterialService;
+    @Autowired
+    private ByteDanceCreativeMapper creativeMapper;
+    @Autowired
+    private IByteDanceVideoInfoService videoInfoService;
+
+    @Override
+    public JSONObject getAdvertiserList(String token, Long accountId) {
+        JSONObject returnJson = new JSONObject();
+        try {
+            String url = "https://ad.oceanengine.com/open_api/2/majordomo/advertiser/select/";
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Content-Type", "application/json");
+            headers.put("Access-Token", token);
+            TreeMap<String, Object> params = new TreeMap<>();
+            params.put("advertiser_id", accountId);
+            String result = HttpUtils.httpGetRequest(url, headers, params);
+            JSONObject jsonObject = JSONObject.parseObject(result);
+            System.err.println(jsonObject);
+            if (Check.isNull(jsonObject)) {
+                throw new Exception("返回结果为空");
+            }
+
+            int code = jsonObject.getInteger("code");
+            if (code == 0) {
+                JSONObject data = jsonObject.getJSONObject("data");
+                if (Check.isNull(data)) {
+                    throw new Exception("data为空");
+                }
+                JSONArray list = data.getJSONArray("list");
+                if (Check.isNull(list)) {
+                    throw new Exception("账户列表为空");
+
+                }
+                returnJson.put("code", 0);
+                returnJson.put("data", list);
+
+            } else {
+                returnJson.put("code", -1);
+            }
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            returnJson.put("code", -1);
+
+        }
+
+
+        return returnJson;
+
+
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserInfo(String accountId, String token) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_advertiser_info");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token);
+        TreeMap<String, Object> params = new TreeMap<>();
+        params.put("advertiser_ids", "[" + accountId + "]");
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        int code = jsonObject.getInteger("code");
+
+        if (code != 0) {
+            log.info("获取广告主信息接口异常==》accountId:{},message:{}", accountId, jsonObject.getString("message"));
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", "获取广告主信息接口异常");
+            return resultMap;
+        }
+        JSONArray data = jsonObject.getJSONArray("data");
+        if (null == data || data.size() <= 0) {
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告主信息不存在");
+            return resultMap;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            resultMap.put("name", dataObject.getString("name"));
+        }
+        resultMap.put("success", true);
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告主信息成功");
+        return resultMap;
+    }
+
+
+    @Override
+    public JSONArray advertiserList(String token) {
+        String url = "https://ad.oceanengine.com/open_api/oauth2/advertiser/get/";
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        TreeMap<String, Object> params = new TreeMap<>();
+        params.put("access_token", token);
+        params.put("secret", bytedanceSecret);
+        params.put("app_id", bytedanceAppId);
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        log.info("返回信息:{}", jsonObject);
+        Integer code = jsonObject.getInteger("code");
+        if (code == 0) {
+            JSONObject dataJson = jsonObject.getJSONObject("data");
+            if (!Check.isNull(dataJson)) {
+                JSONArray listArr = dataJson.getJSONArray("list");
+                if (!Check.isNull(listArr)) {
+                    return listArr;
+                }
+            }
+        }
+        return new JSONArray();
+    }
+
+    @Override
+    public ByteDanceAdvertisePlan getSinglePlanById(CtopOauthToken token, String id){
+        JSONArray getIds = new JSONArray();
+        getIds.add(id);
+        // 请求地址
+        String url = bytedanceApiUrl + bytedanceAdGetUrl;
+        // 请求参数
+        Map<String, Object> filtering = new HashMap<>();
+        filtering.put("ids", getIds);
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", 1);
+        param.put("page_size", 100);
+        param.put("filtering", filtering);
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告计划信息接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return null;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return null;
+        }
+        JSONObject dataObject = data.getJSONObject(0);
+        ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, String.valueOf(token.getAccountId()));
+        BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
+        if (null != deepCpabid) {
+            advertisePlan.setDeepCpaBid(deepCpabid);
+        }
+        return advertisePlan;
+    }
+
+
+    public void getAd(CtopOauthToken token, int pageNum, String ids, String date, String updateDate) {
+        JSONArray getIds = null;
+        if (null != ids && !"".equals(ids)) {
+            String[] idString = ids.split(StringUtils.COMMA);
+            if (idString.length > 0) {
+                for (int i = 0; i < idString.length; i++) {
+                    Long getId = Long.parseLong(idString[i]);
+                    getIds.add(getId);
+                }
+            }
+        }
+
+        // 请求地址
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_get");
+        // 请求参数
+        Map<String, Object> filtering = new HashMap<>();
+        if (null != getIds && getIds.size() > 0) {
+            filtering.put("ids", getIds);
+        }
+        if (null != date && !"".equals(date)) {
+            filtering.put("ad_create_time", date);
+        }
+        if (null != updateDate && !"".equals(updateDate)) {
+            filtering.put("ad_modify_time", updateDate);
+        }
+
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", pageNum);
+        param.put("page_size", 100);
+        param.put("filtering", filtering);
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告计划信息接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, String.valueOf(token.getAccountId()));
+            BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
+            if (null != deepCpabid) {
+                advertisePlan.setDeepCpaBid(deepCpabid);
+            }
+            advertisePlanService.saveOrUpdate(advertisePlan);
+        }
+        getAd(token, pageNum + 1, ids, date, updateDate);
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserPlan(CtopOauthToken token, String ids, String date, String updateDate) {
+        getAd(token, 1, ids, date, updateDate);
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告计划信息成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserBudget(String accountId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        CtopOauthToken cTopOauthToken = tokenService.getOauthTokenByAccountId(accountId);
+        //2: 根据token以及用户id获取用户信息数据
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_get");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", cTopOauthToken.getAccessToken());
+
+        TreeMap<String, Object> params = new TreeMap<>();
+        params.put("advertiser_ids", "[" + cTopOauthToken.getAccountId() + "]");
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告预算信息接口异常==》accountId:{},message:{}", accountId, jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "获取广告预算信息接口异常");
+            return resultMap;
+        }
+        JSONArray data = jsonObject.getJSONArray("data");
+        if (null == data || data.isEmpty()) {
+            log.info("广告主预算信息不存在==》accountId:{},message:{}", accountId, jsonObject.getString("message"));
+            resultMap.put("code", 0);
+            resultMap.put("message", "获取广告主预算信息完成");
+            return resultMap;
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告预算信息完成");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserCreativeMaterial(String accountId, String creativeIds) {
+        Map<String, Object> resultMap = new HashMap<>();
+        CtopOauthToken cTopOauthToken = tokenService.getOauthTokenByAccountId(accountId);
+        //2: 根据token以及用户id获取用户信息数据
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_material_get");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", cTopOauthToken.getAccessToken());
+
+        TreeMap<String, Object> params = new TreeMap<>();
+        params.put("advertiser_id", cTopOauthToken.getAccountId());
+        if (null != creativeIds && !"".equals(creativeIds.trim())) {
+            params.put("creative_ids", "[" + creativeIds + "]");
+        }
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告主创意素材信息接口异常==》accountId:{},message:{}", accountId, jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "获取广告主创意素材信息接口异常");
+            return resultMap;
+        }
+        JSONArray data = jsonObject.getJSONArray("data");
+        if (null == data || data.isEmpty()) {
+            resultMap.put("code", 0);
+            resultMap.put("message", "获取广告主预算信息完成");
+            return resultMap;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceCreativeMaterial material = new ByteDanceCreativeMaterial(dataObject, accountId);
+            creativeMaterialService.saveOrUpdate(material);
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告主预算信息完成");
+        return resultMap;
+    }
+
+
+    private void getCreativeByPage(CtopOauthToken token, String date, int pageNum) {
+        JSONObject resultObject = getCreative(token, date, pageNum);
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("头条创意素材获取接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return;
+        }
+        List<ByteDanceCreative> creatives = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceCreative creative = new ByteDanceCreative(dataObject, token);
+            creatives.add(creative);
+        }
+        creativeMapper.replaceBatch(creatives);
+        getVideoByPage(token, date, pageNum + 1);
+    }
+
+
+    public JSONObject getCreative(CtopOauthToken token, String date, int pageNumber) {
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/creative/get/";
+        // 请求参数
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", pageNumber);
+        param.put("page_size", 100);
+        if (null != date && !"".equals(date.trim())) {
+            JSONObject filtering = new JSONObject();
+            filtering.put("creative_modify_time", date);
+            param.put("filtering", filtering);
+        }
+        return HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+    }
+
+    @Override
+    public Map<String, Object> advertiserPlanUpdateStatus(CtopOauthToken token, String adIds, String optStatus) {
+        Map<String, Object> resultMap = new HashMap<>();
+        JSONArray ids = new JSONArray();
+        String[] getIds = adIds.split(StringUtils.COMMA);
+        if (getIds.length > 0) {
+            for (String getId : getIds) {
+                ids.add(Long.parseLong(getId));
+            }
+        }
+        //2: 根据token以及用户id获取用户信息数据
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_status");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("ad_ids", ids.toJSONString());
+        params.put("opt_status", optStatus);
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        int code = jsonObject.getInteger("code");
+        if (code != 0) {
+            log.error("广告计划更新状态接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告计划更新状态接口异常");
+            return resultMap;
+        }
+        JSONObject data = jsonObject.getJSONObject("data");
+        if (null == data) {
+            log.info("广告计划更新状态异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告计划更新状态异常");
+            return resultMap;
+        }
+        JSONArray getAdIds = data.getJSONArray("ad_ids");
+        if (null != getAdIds && !getAdIds.isEmpty()) {
+            //获取广告计划信息
+            getAdvertiserPlan(token, adIds, null, null);
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告组状态修改成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> advertiserPlanUpdateBid(CtopOauthToken token, String adIds, String bids) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String[] getadIds = adIds.split(StringUtils.COMMA);
+        String[] getBids = bids.split(StringUtils.COMMA);
+        JSONArray data = new JSONArray();
+        if (getadIds.length > 0) {
+            for (int i = 0; i < getadIds.length; i++) {
+                JSONObject object = new JSONObject();
+                Long adId = Long.parseLong(getadIds[i]);
+                Long bid = Long.parseLong(getBids[i]);
+                object.put("ad_id", adId);
+                object.put("bid", bid);
+                data.add(object);
+            }
+        }
+        //2: 根据token以及用户id获取用户信息数据
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_bid");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("data", data.toJSONString());
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        int code = jsonObject.getInteger("code");
+        if (code != 0) {
+            log.info("修改计划出价接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "修改计划出价接口异常");
+            return resultMap;
+        }
+        JSONObject getData = jsonObject.getJSONObject("data");
+        if (null == getData) {
+            log.info("修改计划出价异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "修改计划出价异常");
+            return resultMap;
+        }
+        JSONArray getAdIds = getData.getJSONArray("ad_ids");
+        if (null != getAdIds && !getAdIds.isEmpty()) {
+            //获取广告计划信息
+            getAdvertiserPlan(token, adIds, null, null);
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "修改计划出价成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> advertiserPlanUpdateBudget(CtopOauthToken token, String adIds, String budgets) {
+        Map<String, Object> resultMap = new HashMap<>();
+        JSONArray data = new JSONArray();
+        String[] getadIds = adIds.split(StringUtils.COMMA);
+        String[] getBudgets = budgets.split(StringUtils.COMMA);
+        if (getadIds.length > 0) {
+            for (int i = 0; i < getadIds.length; i++) {
+                JSONObject object = new JSONObject();
+                Long adId = Long.parseLong(getadIds[i]);
+                Long budget = Long.parseLong(getBudgets[i]);
+                object.put("ad_id", adId);
+                object.put("budget", budget);
+                data.add(object);
+            }
+        }
+        //2: 根据token以及用户id获取用户信息数据
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_budget");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("data", data.toJSONString());
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.info("修改计划预算接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "修改计划预算接口异常");
+            return resultMap;
+        }
+        JSONObject getData = jsonObject.getJSONObject("data");
+        if (null == getData) {
+            log.info("修改计划预算异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "修改计划预算异常");
+            return resultMap;
+        }
+        JSONArray getAdIds = getData.getJSONArray("ad_ids");
+        if (null != getAdIds && !getAdIds.isEmpty()) {
+            //获取广告计划信息
+            getAdvertiserPlan(token, adIds, null, null);
+        }
+        resultMap.put("code", 0);
+        resultMap.put("message", "修改计划预算成功");
+        return resultMap;
+    }
+
+    /**
+     * 查询人群包信息
+     *
+     * @return
+     */
+    @Override
+    public Map<String, Object> advertiserCustomAudienceSelect(String accountId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        if (null == accountId || "".equals(accountId.trim())) {
+            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_PARAM_ERROR);
+            return resultMap;
+        }
+        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+        if (null == token) {
+            ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_PARAM_ERROR);
+            return resultMap;
+        }
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_dmp_custom_audience_select");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        TreeMap<String, Object> params = new TreeMap<>();
+        params.put("select_type", "0");
+        params.put("advertiser_id", token.getAccountId() + "");
+        params.put("limit", "100");
+        params.put("offset", "0");
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+        String message = jsonObject.getString("message");
+        if (null == code || !code.equals(0)) {
+            log.info("获取人群包信息接口异常==》accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
+            resultMap.put("message", message);
+            resultMap.put("code", -1);
+            return resultMap;
+        }
+        JSONArray data = jsonObject.getJSONObject("data").getJSONArray("custom_audience_list");
+        if (null == data || data.isEmpty()) {
+            log.info("人群包信息不存在==》accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
+            resultMap.put("message", "人群包信息不存在");
+            resultMap.put("code", -1);
+            return resultMap;
+        }
+        resultMap.put("success", true);
+        resultMap.put("message", "人群包信息获取成功");
+        resultMap.put("data", data);
+        resultMap.put("code", 0);
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserCampaignList(String accountId) {
+        Map<String, Object> resultMap = new HashMap<>();
+        CtopOauthToken cTopOauthToken = tokenService.getOauthTokenByAccountId(accountId);
+        String url = bytedanceApiUrl + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_get");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", cTopOauthToken.getAccessToken());
+
+        TreeMap<String, Object> params = new TreeMap<>();
+        params.put("advertiser_id", cTopOauthToken.getAccountId());
+        params.put("page", 1);
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告组信息接口异常==》accountId:{},message:{}", accountId, jsonObject.getString("message"));
+            resultMap.put("code", code);
+            resultMap.put("message", jsonObject.getString("message"));
+            return resultMap;
+        }
+        JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            log.info("获取广告组信息为空==》accountId:{},message:{}", accountId, jsonObject.getString("message"));
+            resultMap.put("code", code);
+            resultMap.put("message", "获取广告组信息为空");
+            return resultMap;
+        }
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
+        resultMap.put("data", data);
+        return resultMap;
+    }
+
+    /**
+     * 获取流量包数据接口
+     *
+     * @param accountId
+     * @return
+     */
+    @Override
+    public Map<String, Object> flowPackageGet(String accountId) {
+        JSONObject jsonObject = flowPackageGetJsonObject(accountId);
+        JSONObject result = new JSONObject();
+        Integer code = jsonObject.getInteger("code");
+        String message = jsonObject.getString("message");
+        result.put("code", code);
+        result.put("message", message);
+        if (null == code || code != 0) {
+            result.put("success", false);
+            return result;
+        }
+        JSONArray packageList = jsonObject.getJSONObject("data").getJSONArray("list");
+        if (null != packageList && !packageList.isEmpty()) {
+            JSONArray packageArray = new JSONArray();
+            for (int i = 0; i < packageList.size(); i++) {
+                JSONObject packageObject = packageList.getJSONObject(i);
+                packageObject.remove("rit");
+                String status = packageObject.getString("status");
+                if ("FLOW_PACKAGE_ENABLE".equals(status)) {
+                    packageArray.add(packageObject);
+                }
+            }
+            result.put("data", packageArray);
+        }
+        result.put("success", true);
+        return result;
+    }
+
+    @Override
+    public void getMaterialList(CtopOauthToken token) {
+        getVideoByPage(token, "", 1);
+        getImageByPage(token, "", 1);
+    }
+
+    @Autowired
+    private IBytedanceImageInfoService imageInfoService;
+
+    @Override
+    public void getImageByPage(CtopOauthToken token, String imageIds, int page) {
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/file/image/get/";
+        // 请求参数
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", page);
+        param.put("page_size", 100);
+        if (null != imageIds && !"".equals(imageIds.trim())) {
+            String[] getIds = imageIds.split(StringUtils.COMMA);
+            if (getIds.length > 0) {
+                JSONObject filter = new JSONObject();
+                JSONArray idArray = new JSONArray();
+                Collections.addAll(idArray, getIds);
+                filter.put("image_ids", idArray);
+                param.put("filtering", filter);
+            }
+        }
+
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        if (null == resultObject) {
+            log.error("获取图片素材库接口异常==》accountId:{}", token.getAccountId());
+            return;
+        }
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取图片素材库接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            log.info("获取图片素材完成==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        List<BytedanceImageInfo> videoInfoList = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            BytedanceImageInfo imageInfo = new BytedanceImageInfo(dataObject, token);
+            videoInfoList.add(imageInfo);
+        }
+        imageInfoService.replaceBatch(videoInfoList);
+        getImageByPage(token, imageIds, page + 1);
+    }
+
+    private void getVideoByPage(CtopOauthToken token, String videoIds, int page) {
+        // 请求地址
+        String url = "https://ad.oceanengine.com/open_api/2/file/video/get/";
+        // 请求参数
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", token.getAccountId());
+        param.put("page", page);
+        param.put("page_size", 100);
+        if (null != videoIds && !"".equals(videoIds.trim())) {
+            String[] getIds = videoIds.split(StringUtils.COMMA);
+            if (getIds.length > 0) {
+                JSONObject filter = new JSONObject();
+                JSONArray idArray = new JSONArray();
+                Collections.addAll(idArray, getIds);
+                filter.put("video_ids", idArray);
+                param.put("filtering", filter);
+            }
+        }
+
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, param);
+        if (null == resultObject) {
+            log.error("获取视频素材库接口异常==》accountId:{}", token.getAccountId());
+            return;
+        }
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取视频素材库接口异常==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            log.info("获取视频素材完成==》accountId:{},message:{}", token.getAccountId(), resultObject.getString("message"));
+            return;
+        }
+        List<ByteDanceVideoInfo> videoInfoList = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceVideoInfo videoInfo = new ByteDanceVideoInfo(dataObject, token);
+            videoInfoList.add(videoInfo);
+        }
+        videoInfoService.replaceBatch(videoInfoList);
+        getVideoByPage(token, videoIds, page + 1);
+    }
+
+    public JSONObject flowPackageGetJsonObject(String accountId) {
+        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+        // 请求地址
+        String url = "https://ad.toutiao.com/open_api/2/tools/union/flow_package/get/";
+        // 请求参数
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("page", 1);
+        params.put("page_size", 100);
+        return HttpUtils.bytedanceGetRequest(token.getAccessToken(), url, params);
+    }
+
+
+    @Override
+    public void getBytedancePlanList(String accountId, String accessToken, int pageNum, String createDate, String updateDate) {
+        // 请求地址
+        String url = bytedanceApiUrl + bytedanceAdGetUrl;
+        // 请求参数
+        Map<String, Object> filtering = new HashMap<>();
+        if (null != createDate && !"".equals(createDate)) {
+            filtering.put("ad_create_time", createDate);
+        }
+        if (null != updateDate && !"".equals(updateDate)) {
+            filtering.put("ad_modify_time", updateDate);
+        }
+
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id", accountId);
+        param.put("page", pageNum);
+        param.put("page_size", 1000);
+        param.put("filtering", filtering);
+        JSONObject resultObject = HttpUtils.bytedanceGetRequest(accessToken, url, param);
+        Integer code = resultObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告计划信息接口异常==》accountId:{},message:{}", accountId, resultObject.getString("message"));
+            return;
+        }
+        JSONArray data = resultObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceAdvertisePlan advertisePlan = new ByteDanceAdvertisePlan(dataObject, accountId);
+            BigDecimal deepCpabid = dataObject.getBigDecimal("deep_cpabid");
+            if (null != deepCpabid) {
+                advertisePlan.setDeepCpaBid(deepCpabid);
+            }
+            //   advertisePlanService.saveOrUpdate(advertisePlan);
+        }
+        getBytedancePlanList(accountId, accessToken, pageNum + 1, createDate, updateDate);
+    }
+
+
+}

+ 18 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertiserServiceImpl.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertiser;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceAdvertiserMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAdvertiserService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Description: 今日头条广告主信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+@Service
+public class ByteDanceAdvertiserServiceImpl extends ServiceImpl<ByteDanceAdvertiserMapper, ByteDanceAdvertiser> implements IByteDanceAdvertiserService {
+
+}

+ 18 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceByteDanceAudiencePackageServiceImpl.java

@@ -0,0 +1,18 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAudiencePackage;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceAudiencePackageMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAudiencePackageService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 头条定向包
+ * @author jeecg-boot
+ * @date   2020-07-22
+ * @version V1.0
+ */
+@Service
+public class ByteDanceByteDanceAudiencePackageServiceImpl extends ServiceImpl<ByteDanceAudiencePackageMapper, ByteDanceAudiencePackage> implements IByteDanceAudiencePackageService {
+
+}

+ 249 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceCampaignServiceImpl.java

@@ -0,0 +1,249 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCampaign;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCampaignMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceCampaignService;
+import org.jeecg.modules.bytedance.advertise.vo.BytedanceCampaignEditVo;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
+import org.jeecg.modules.bytedance.common.utils.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * @Description: 今日头条广告组信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+
+@Service
+@Slf4j
+public class ByteDanceCampaignServiceImpl extends ServiceImpl<ByteDanceCampaignMapper, ByteDanceCampaign> implements IByteDanceCampaignService {
+    @Resource
+    private ByteDanceCampaignMapper campaignMapper;
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    /**
+     * 每个广告主账号下最多可允许创建500个广告组,如超出需要先删除一部分广告组后才可继续创建。
+     * @param accountId
+     * @param campaignName
+     * @param operation
+     * @param budgetMode
+     * @param budget
+     * @param landingType
+     * @param uniqueFk
+     * @return
+     */
+    @Override
+    public Map<String, Object> createCampaign(Long accountId, String campaignName, String operation, String budgetMode, String budget, String landingType, String uniqueFk) {
+        Map<String,Object>result = new HashMap<>();
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        // 请求地址
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_create");
+        // 请求参数
+        JSONObject param = new JSONObject();
+        param.put("advertiser_id",token.getAccountId());
+        param.put("campaign_name",campaignName);
+        if(null!=operation&&!"".equals(operation.trim())){
+            param.put("operation",operation);
+        }
+        param.put("budget_mode", budgetMode);
+        if(null != budget&&!"".equals(budget.trim())){
+            param.put("budget",budget);
+        }
+        param.put("landing_type", landingType);
+        if(null != uniqueFk&&!"".equals(uniqueFk.trim())){
+            param.put("unique_fk",uniqueFk);
+        }
+        JSONObject data = HttpUtils.bytedancePostRequest(token.getAccessToken(),url,param);
+        if(data == null){
+            log.error("创建广告组异常=>param:{}",param.toJSONString());
+            ResultMapUtils.setResultMap(result, StatusCode.BYTEDACNE_API_GROUP_CREATE_ERROR);
+            return result;
+        }
+        Integer code = data.getInteger("code");
+        String message = data.getString("message");
+        if(null == code||!code.equals(0)){
+            log.error("获取广告组数据异常=>{},parmas:{}",message,param.toJSONString());
+            ResultMapUtils.setResultMap(result,-1,message,false);
+            return result;
+        }
+        Long campaignId = data.getJSONObject("data").getLong("campaign_id");
+        this.getAdvertiserCampaign(token,null,null);
+        ResultMapUtils.setResultMap(result,StatusCode.COMMON_SUCCESS);
+        result.put("campaign_id",campaignId);
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> updateCampaign(CtopOauthToken token, Long campaignId, String campaignName,String budgetMode, Integer budget) {
+        Map<String, Object> resultMap = new HashMap<>();
+        ByteDanceCampaign campaign = this.getById(campaignId);
+        //2: 根据token以及用户id获取用户信息数据
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_update");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("campaign_id", campaignId);
+        params.put("modify_time", campaign.getModifyTime());
+        if (null != campaignName && !"".equals(campaignName.trim())) {
+            params.put("campaign_name", campaignName);
+        }
+        if (null != budgetMode && !"".equals(budgetMode.trim())) {
+            params.put("budget_mode", budgetMode);
+        }
+        if (null != budget) {
+            params.put("budget", budget);
+        }
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.info("广告组更新接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", jsonObject.getString("message"));
+            resultMap.put("success",false);
+            return resultMap;
+        }
+        JSONObject data = jsonObject.getJSONObject("data");
+        if (null == data) {
+            log.info("广告组更新异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", jsonObject.getString("message"));
+            resultMap.put("success",false);
+            return resultMap;
+        }
+        this.getAdvertiserCampaign(token,campaignId+"",null);
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告组信息修改成功");
+        resultMap.put("success",true);
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> getAdvertiserCampaign(CtopOauthToken token, String ids, String date) {
+        getAdvertiserCampaignByPageNumber(token, 1, ids, date);
+        Map<String, Object> resultMap = new HashMap<>();
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告組信息成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object>  updateCampaign(BytedanceCampaignEditVo editVo) {
+        Map<String,Object>result = new HashMap<>();
+        CtopOauthToken token = tokenService.getTokenByAccountId(editVo.getAccountId());
+        if(null == token){
+            ResultMapUtils.setResultMap(result, StatusCode.COMMON_PARAM_ERROR);
+            return result;
+        }
+        this.getAdvertiserCampaign(token,editVo.getId()+"",null);
+        return this.updateCampaign(token,editVo.getId(),editVo.getCampaignName(),editVo.getBudgetMode(),editVo.getBudget());
+    }
+
+    private void getAdvertiserCampaignByPageNumber(CtopOauthToken token, Integer pageNumber, String ids, String date) {
+        //2: 根据token以及用户id获取用户信息数据
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_get");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        TreeMap<String, Object> params = new TreeMap<>();
+        JSONObject filtering = new JSONObject();
+        filtering.put("status","CAMPAIGN_STATUS_ALL");
+        if (null != ids && !"".equals(ids.trim())) {
+            String[] idsArray = ids.split(StringUtils.COMMA);
+            JSONArray filterIdsArray = new JSONArray();
+            for (int i = 0; i < idsArray.length; i++) {
+                Long id = Long.parseLong(idsArray[i]);
+                filterIdsArray.add(id);
+            }
+            filtering.put("ids", filterIdsArray);
+        }
+        if (null != date && !"".equals(date)) {
+            filtering.put("campaign_create_time", date);
+        }
+        params.put("filtering", filtering.toJSONString());
+        params.put("advertiser_id", token.getAccountId());
+        params.put("page", pageNumber + "");
+        params.put("page_size", 100);
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+        if (null == code || !code.equals(0)) {
+            log.error("获取广告组信息接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            return;
+        }
+        JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            return;
+        }
+        List<ByteDanceCampaign> campaigns = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceCampaign campaign = new ByteDanceCampaign(dataObject,token.getAccountId());
+            campaigns.add(campaign);
+        }
+        campaignMapper.replaceBatch(campaigns);
+        getAdvertiserCampaignByPageNumber(token, pageNumber + 1, ids, date);
+    }
+
+    @Override
+    public Map<String, Object> updateCampaignStatus(Long accountId, String campaignIds, String optStatus) {
+        Map<String, Object> resultMap = new HashMap<>();
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        this.getAdvertiserCampaign(token,null,null);
+        JSONArray ids = new JSONArray();
+        String[] getIds = campaignIds.split(StringUtils.COMMA);
+        if (null != getIds && getIds.length > 0) {
+            for (int i = 0; i < getIds.length; i++) {
+                ids.add(Long.parseLong(getIds[i]));
+            }
+        }
+        //2: 根据token以及用户id获取用户信息数据
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_update_status");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("campaign_ids", ids);
+        params.put("opt_status", optStatus);
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            log.info("广告组更新状态接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告组更新0状态接口异常");
+            resultMap.put("success", false);
+            return resultMap;
+        }
+        JSONObject data = jsonObject.getJSONObject("data");
+        if (null == data) {
+            log.info("广告组更新状态异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告组操作异常");
+            resultMap.put("success", false);
+            return resultMap;
+        }
+        this.getAdvertiserCampaign(token,null,null);
+        resultMap.put("code", 0);
+        resultMap.put("message", "操作成功");
+        resultMap.put("success", true);
+        return resultMap;
+    }
+}

+ 20 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceCreativeMaterialServiceImpl.java

@@ -0,0 +1,20 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreativeMaterial;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCreativeMaterialMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceCreativeMaterialService;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Description: 今日头条创意素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+@Service
+@Primary
+public class ByteDanceCreativeMaterialServiceImpl extends ServiceImpl<ByteDanceCreativeMaterialMapper, ByteDanceCreativeMaterial> implements IByteDanceCreativeMaterialService {
+
+}

+ 907 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceCreativeServiceImpl.java

@@ -0,0 +1,907 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreative;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceCreativeMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAdvertisePlanService;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceCreativeService;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
+import org.jeecg.modules.bytedance.common.utils.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * @Description: 今日头条创意信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-22
+ * @Version: V1.0
+ */
+@Slf4j
+@Service
+public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeMapper, ByteDanceCreative> implements IByteDanceCreativeService {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Resource
+    private ByteDanceCreativeMapper creativeMapper;
+    @Autowired
+    private IByteDanceAdvertisePlanService byteDanceAdvertisePlanService;
+
+    /**
+     * 更改创意状态
+     * @param accountId
+     * @param creativeIds
+     * @param optStatus
+     * @return
+     */
+    @Override
+    public Map<String, Object> advertiserCreativeUpdateStatus(CtopOauthToken cTopOauthToken,Long accountId, String creativeIds, String optStatus) {
+        Map<String, Object> resultMap = new HashMap<>();
+        JSONArray ids = new JSONArray();
+        String[] getCreativeIds = creativeIds.split(StringUtils.COMMA);
+        if (getCreativeIds.length > 0) {
+            for (int i = 0; i < getCreativeIds.length; i++) {
+                ids.add(Long.parseLong(getCreativeIds[i]));
+            }
+        }
+        //2: 根据token以及用户id获取用户信息数据
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_update_status");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", cTopOauthToken.getAccessToken());
+
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", cTopOauthToken.getAccountId());
+        params.put("creative_ids", ids.toJSONString());
+        params.put("opt_status", optStatus);
+        String result = HttpUtils.httpPostRequest(url, params, headers);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+        String message = jsonObject.getString("message");
+        if (null == code || !code.equals(0)) {
+            log.info("修改创意状态接口异常==》accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        JSONObject data = jsonObject.getJSONObject("data");
+        if (null == data) {
+            log.info("修改创意状态异常==》accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        JSONArray returnCreativeIds = data.getJSONArray("creative_ids");
+        if (null != returnCreativeIds && !returnCreativeIds.isEmpty()) {
+            getAdvertiserCreative(cTopOauthToken, creativeIds, null);
+        }
+        resultMap.put("success", true);
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告创意状态修改成功");
+        return resultMap;
+    }
+
+    @Override
+    public void replaceBatch(List<ByteDanceCreative> creatives) {
+        creativeMapper.replaceBatch(creatives);
+    }
+
+    /**
+     * 获取创意列表,入库
+     * @param token
+     * @param ids
+     * @param date
+     * @return
+     */
+    @Override
+    public Map<String, Object> getAdvertiserCreative(CtopOauthToken token, String ids, String date) {
+        Map<String, Object> resultMap = new HashMap<>();
+        getAdvertiserCreativeByPageNumber(token, 1, ids, date);
+        resultMap.put("code", 0);
+        resultMap.put("message", "获取广告主广告创意信息完成");
+        return resultMap;
+    }
+
+    public void getAdvertiserCreativeByPageNumber(CtopOauthToken token, Integer pageNumber, String ids, String date) {
+        //2: 根据token以及用户id获取用户信息数据
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_get");
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        TreeMap<String, Object> params = new TreeMap<>();
+        JSONObject filtering = new JSONObject();
+        if (null != ids && !"".equals(ids.trim())) {
+            String[] idsArray = ids.split(StringUtils.COMMA);
+            JSONArray filterIdsArray = new JSONArray();
+            for (int i = 0; i < idsArray.length; i++) {
+                Long id = Long.parseLong(idsArray[i]);
+                filterIdsArray.add(id);
+            }
+            filtering.put("ids", filterIdsArray);
+        }
+        if (null != date && !"".equals(date)) {
+            filtering.put("creative_create_time", date);
+        }
+        params.put("filtering", filtering.toJSONString());
+        params.put("advertiser_id", token.getAccountId());
+        params.put("page", pageNumber + "");
+        params.put("page_size",100);
+        String result = HttpUtils.httpGetRequest(url, headers, params);
+        JSONObject jsonObject = JSONObject.parseObject(result);
+        Integer code = jsonObject.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            log.info("获取广告主广告创意信息接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            return;
+        }
+        JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
+        if (null == data || data.isEmpty()) {
+            log.info("广告主广告创意信息不存在==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            return;
+        }
+        for (int i = 0; i < data.size(); i++) {
+            JSONObject dataObject = data.getJSONObject(i);
+            ByteDanceCreative creative = new ByteDanceCreative(dataObject, token);
+            this.saveOrUpdate(creative);
+        }
+        getAdvertiserCreativeByPageNumber(token, pageNumber + 1, ids, date);
+    }
+
+    /**
+     * 创建创意
+     * @param accountId
+     * @param adId
+     * @param data
+     * @return
+     */
+    @Override
+    public Map<String, Object> creativeCreate(String accountId, Long adId, JSONObject data) {
+        Map<String, Object> resultMap = new HashMap<>();
+        //1:获取token
+        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
+        data.put("advertiser_id", token.getAccountId());
+        data.put("ad_id", adId);
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_create_v2");
+        JSONObject result = HttpUtils.bytedancePostRequest(token.getAccessToken(),url,data);
+        Integer code = result.getInteger("code");
+        String message = result.getString("message");
+        if (null == code || code != 0) {
+            log.info("广告创意创建失败,accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告计划("+adId+"):"+message);
+            return resultMap;
+        }
+        Thread thread = new Thread(()->getAdvertiserCreative(token, null, null));
+        thread.start();
+
+        resultMap.put("success", true);
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告计划("+adId+"):"+"创意创建成功");
+        return resultMap;
+    }
+    /**
+     * 获取创意详细信息
+     * @return
+     */
+    @Override
+    public Map<String, Object> getCreativeDetail(CtopOauthToken token, Long planId){
+        Map<String,Object>resultMap = new HashMap<>();
+        if(null == planId||planId == 0||null == token){
+            ResultMapUtils.setResultMap(resultMap,StatusCode.COMMON_PARAM_ERROR);
+            resultMap.put("data",null);
+            return resultMap;
+        }
+
+        ByteDanceAdvertisePlan plan = byteDanceAdvertisePlanService.getById(planId);
+        if(null == plan|| "AD_STATUS_DELETE".equals(plan.getOptStatus())){
+            ResultMapUtils.setResultMap(resultMap,StatusCode.BYTEDANCE_ACCOUNT_DATA_NOT_EXIST);
+            resultMap.put("data",null);
+            return resultMap;
+        }
+        // 请求地址
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_read");
+        // 请求参数
+        JSONObject data = new JSONObject();
+        data.put("advertiser_id", token.getAccountId());
+        data.put("ad_id",planId);
+        JSONObject result = HttpUtils.bytedanceGetRequest(token.getAccessToken(),url,data);
+        if(null == result){
+            ResultMapUtils.setResultMap(resultMap,StatusCode.COMMON_INTERNET_ERROR);
+            resultMap.put("data",null);
+            return resultMap;
+        }
+        Integer code = result.getInteger("code");
+        String message = result.getString("message");
+        if (null ==  code) {
+            log.info("广告创意获取详情失败,accountId:{},message:{}", token.getAccountId(), message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            result.put("data",null);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        if(code == 40001){
+            //尚未创建创意
+            resultMap.put("success", true);
+            resultMap.put("code", 0);
+            result.put("data",null);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        if(code!=0){
+            log.info("广告创意获取详情失败,accountId:{},message:{}", token.getAccountId(), message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            result.put("data",null);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        JSONObject getData = result.getJSONObject("data");
+        resultMap.put("data",formatData(getData));
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS);
+        return resultMap;
+    }
+
+    private JSONObject formatData(JSONObject getData) {
+        JSONObject data = new JSONObject();
+        Long advertiserId = getData.getLong("advertiser_id");
+        if(null!=advertiserId&&advertiserId!=0){
+            data.put("advertiserId",advertiserId);
+        }
+        Long adId = getData.getLong("ad_id");
+        if(null!=adId&&adId!=0){
+            data.put("adId",adId);
+        }
+        String modifyTime = getData.getString("modify_time");
+        if(null!=modifyTime&&!"".equals(modifyTime.trim())){
+            data.put("modifyTime",modifyTime);
+        }
+        String trackUrl = getData.getString("track_url");
+        if(null!=trackUrl&&!"".equals(trackUrl.trim())){
+            data.put("trackUrl",trackUrl);
+        }
+        String actionTrackUrl = getData.getString("action_track_url");
+        if(null!=actionTrackUrl&&!"".equals(actionTrackUrl.trim())){
+            data.put("actionTrackUrl",actionTrackUrl);
+        }
+        String videoPlayEffectiveTrackUrl = getData.getString("video_play_effective_track_url");
+        if(null!=videoPlayEffectiveTrackUrl&&!"".equals(videoPlayEffectiveTrackUrl.trim())){
+            data.put("videoPlayEffectiveTrackUrl",videoPlayEffectiveTrackUrl);
+        }
+        String videoPlayDoneTrackUrl = getData.getString("video_play_done_track_url");
+        if(null!=videoPlayDoneTrackUrl&&!"".equals(videoPlayDoneTrackUrl.trim())){
+            data.put("videoPlayDoneTrackUrl",videoPlayDoneTrackUrl);
+        }
+        String videoPlayTrackUrl = getData.getString("video_play_track_url");
+        if(null!=videoPlayTrackUrl&&!"".equals(videoPlayTrackUrl.trim())){
+            data.put("videoPlayTrackUrl",videoPlayTrackUrl);
+        }
+        Integer isCommentDisable = getData.getInteger("is_comment_disable");
+        if(null!=isCommentDisable){
+            data.put("isCommentDisable",isCommentDisable);
+        }
+        Integer closeVideoDetail = getData.getInteger("close_video_detail");
+        if(null!=closeVideoDetail){
+            data.put("closeVideoDetail",closeVideoDetail);
+        }
+        String creativeDisplayMode = getData.getString("creative_display_mode");
+        if(null!=creativeDisplayMode&&!"".equals(creativeDisplayMode.trim())){
+            data.put("creativeDisplayMode",creativeDisplayMode);
+        }
+        Long smartInventory = getData.getLong("smart_inventory");
+        if(null!=smartInventory&&smartInventory!=0){
+            data.put("smartInventory",smartInventory);
+        }
+        String sceneInventory = getData.getString("scene_inventory");
+        if(null!=sceneInventory&&!"".equals(sceneInventory.trim())){
+            data.put("sceneInventory",sceneInventory);
+        }
+        Long generateDerivedAd = getData.getLong("generate_derived_ad");
+        if(null!=generateDerivedAd&&generateDerivedAd!=0){
+            data.put("generateDerivedAd",generateDerivedAd);
+        }
+        JSONArray inventoryType = getData.getJSONArray("inventory_type");
+        if(null!=inventoryType&&!inventoryType.isEmpty()){
+            data.put("inventoryType",inventoryType);
+        }
+        String source = getData.getString("source");
+        if(null!=source&&!"".equals(source.trim())){
+            data.put("source",source);
+        }
+        String appName = getData.getString("app_name");
+        if(null!=appName&&!"".equals(appName.trim())){
+            data.put("appName",appName);
+        }
+        String webUrl = getData.getString("web_url");
+        if(null!=webUrl&&!"".equals(webUrl.trim())){
+            data.put("webUrl",webUrl);
+        }
+        JSONArray adKeywords = getData.getJSONArray("ad_keywords");
+        if(null!=adKeywords&&!adKeywords.isEmpty()){
+            data.put("adKeywords",adKeywords);
+        }
+        Long thirdIndustryId = getData.getLong("third_industry_id");
+        if(null!=thirdIndustryId&&thirdIndustryId!=0){
+            data.put("thirdIndustryId",thirdIndustryId);
+        }
+        String advancedCreativeType = getData.getString("advanced_creative_type");
+        if(null!=advancedCreativeType&&!"".equals(advancedCreativeType.trim())){
+            data.put("advancedCreativeType",advancedCreativeType);
+        }
+        String advancedCreativeTitle = getData.getString("advanced_creative_title");
+        if(null!=advancedCreativeTitle&&!"".equals(advancedCreativeTitle.trim())){
+            data.put("advancedCreativeTitle",advancedCreativeTitle);
+        }
+        String phoneNumber = getData.getString("phone_number");
+        if(null!=phoneNumber&&!"".equals(phoneNumber.trim())){
+            data.put("phoneNumber",phoneNumber);
+        }
+        String buttonText = getData.getString("button_text");
+        if(null!=buttonText&&!"".equals(buttonText.trim())){
+            data.put("buttonText",buttonText);
+        }
+        String actionText = getData.getString("action_text");
+        if(null!=actionText&&!"".equals(actionText.trim())){
+            data.put("actionText",actionText);
+        }
+        String formUrl = getData.getString("form_url");
+        if(null!=formUrl&&!"".equals(formUrl.trim())){
+            data.put("formUrl",formUrl);
+        }
+        String creativeMaterialMode = getData.getString("creative_material_mode");
+        if(null!=creativeMaterialMode&&!"".equals(creativeMaterialMode.trim())){
+            data.put("creativeMaterialMode",creativeMaterialMode);
+        }
+        String iesCoreUserId = getData.getString("ies_core_user_id");
+        if(null!=iesCoreUserId&&!"".equals(iesCoreUserId.trim())){
+            data.put("iesCoreUserId",iesCoreUserId);
+        }
+        Long isFeedAndFavSee = getData.getLong("is_feed_and_fav_see");
+        if(null!=isFeedAndFavSee){
+            data.put("isFeedAndFavSee",isFeedAndFavSee);
+        }
+        JSONArray commerceCards = getData.getJSONArray("commerce_cards");
+        if(null!=commerceCards&&!commerceCards.isEmpty()){
+            data.put("commerceCards",commerceCards);
+        }
+        String playableUrl = getData.getString("playable_url");
+        if(null!=playableUrl&&!"".equals(playableUrl.trim())){
+            data.put("playableUrl",playableUrl);
+        }
+        Long proceduralPackageId = getData.getLong("procedural_package_id");
+        if(null!=proceduralPackageId&&proceduralPackageId!=0){
+            data.put("proceduralPackageId",proceduralPackageId);
+        }
+        Long proceduralPackageVersion = getData.getLong("procedural_package_version");
+        if(null!=proceduralPackageVersion&&proceduralPackageVersion!=0){
+            data.put("proceduralPackageVersion",proceduralPackageVersion);
+        }
+        Long isPresentedVideo = getData.getLong("is_presented_video");
+        if(null!=isPresentedVideo){
+            data.put("isPresentedVideo",isPresentedVideo);
+        }
+        String subTitle = getData.getString("sub_title");
+        if(null!=subTitle&&!"".equals(subTitle.trim())){
+            data.put("subTitle",subTitle);
+        }
+        Long creativeAutoGenerateSwitch = getData.getLong("creative_auto_generate_switch");
+        if(null!=creativeAutoGenerateSwitch){
+            data.put("creativeAutoGenerateSwitch",creativeAutoGenerateSwitch);
+        }
+        String trackUrlSendType = getData.getString("track_url_send_type");
+        if(null!=trackUrlSendType&&!"".equals(trackUrlSendType.trim())){
+            data.put("trackUrlSendType",trackUrlSendType);
+        }
+        JSONArray subLinkIdList = getData.getJSONArray("sub_link_id_list");
+        if(null!=subLinkIdList&&!subLinkIdList.isEmpty()){
+            data.put("subLinkIdList",subLinkIdList);
+        }
+        JSONArray titleList = getData.getJSONArray("title_list");
+        if(null!=titleList&&!titleList.isEmpty()){
+            JSONArray titleArray = new JSONArray();
+            for (int i=0;i<titleList.size();i++){
+                JSONObject title = titleList.getJSONObject(i);
+                JSONArray creativeWordIds = title.getJSONArray("creative_word_ids");
+                JSONArray dpaDictIds = title.getJSONArray("dpa_dict_ids");
+                title.remove("creative_word_ids");
+                title.remove("dpa_dict_ids");
+                title.put("creativeWordIds",creativeWordIds);
+                title.put("dpaDictIds",dpaDictIds);
+                titleArray.add(title);
+            }
+            data.put("titleList",titleArray);
+        }
+        JSONArray imageList = getData.getJSONArray("image_list");
+        if(null!=imageList&&!imageList.isEmpty()){
+            JSONArray imageArray = new JSONArray();
+            for (int i=0;i<imageList.size();i++){
+                JSONObject getImage = imageList.getJSONObject(i);
+                JSONObject setImage = new JSONObject();
+                String imageMode = getImage.getString("image_mode");
+                setImage.put("imageMode",imageMode);
+                String imageId = getImage.getString("image_id");
+                if(null!=imageId&&!"".equals(imageId.trim())){
+                    setImage.put("imageId",imageId);
+                    if(imageId.contains("web")){
+                        setImage.put("imageUrl","https://sf6-ttcdn-tos.pstatp.com/obj/"+imageId);
+                    }else{
+                        setImage.put("imageUrl","https://sf6-ttcdn-tos.pstatp.com/obj/mosaic-legacy/"+imageId);
+                    }
+                }
+                String videoId = getImage.getString("video_id");
+                if(null!=videoId&&!"".equals(videoId.trim())){
+                    setImage.put("videoId",videoId);
+                    setImage.put("videoUrl","https://aweme.snssdk.com/aweme/v1/playwm/?video_id="+videoId+"&line=0");
+                }
+                JSONArray imageIds = getImage.getJSONArray("image_ids");
+                if(null!=imageIds&&!imageIds.isEmpty()){
+                    setImage.put("imageIds",imageIds);
+                }
+                String templateId = getImage.getString("template_id");
+                if(null!=templateId&&!"".equals(templateId.trim())){
+                    setImage.put("templateId",templateId);
+                }
+                imageArray.add(setImage);
+            }
+            data.put("imageList",imageArray);
+        }
+        JSONArray creativeList = getData.getJSONArray("creatives");
+        if(null!=creativeList&&!creativeList.isEmpty()){
+            JSONArray creativeArray = new JSONArray();
+            for (int i=0;i<creativeList.size();i++){
+                JSONObject getCreative = creativeList.getJSONObject(i);
+                JSONObject setCreative = new JSONObject();
+                String creative_id = getCreative.getString("creative_id");
+                if(null!=creative_id&&!"".equals(creative_id.trim())){
+                    setCreative.put("creative_id",creative_id);
+                }
+                String title = getCreative.getString("title");
+                if(null!=title&&!"".equals(title.trim())){
+                    setCreative.put("title",title);
+                }
+                JSONArray creativeWordIds = getCreative.getJSONArray("creative_word_ids");
+                if(null!=creativeWordIds&&!creativeWordIds.isEmpty()){
+                    setCreative.put("creativeWordIds",creativeWordIds);
+                }
+                JSONArray dpaDictIds = getCreative.getJSONArray("dpa_dict_ids");
+                if(null!=dpaDictIds&&!dpaDictIds.isEmpty()){
+                    setCreative.put("dpaDictIds",dpaDictIds);
+                }
+                String imageMode = getCreative.getString("image_mode");
+                if(null!=imageMode&&!"".equals(imageMode.trim())){
+                    setCreative.put("imageMode",imageMode);
+                }
+                JSONArray imageIds = getCreative.getJSONArray("imageIds");
+                if(null!=imageIds&&!imageIds.isEmpty()){
+                    setCreative.put("imageIds",imageIds);
+                }
+                String imageId = getCreative.getString("image_id");
+                if(null!=imageId&&!"".equals(imageId.trim())){
+                    setCreative.put("imageId",imageId);
+                    setCreative.put("imageUrl","https://sf6-ttcdn-tos.pstatp.com/obj/mosaic-legacy/"+imageId);
+                }
+                String videoId = getCreative.getString("video_id");
+                if(null!=videoId&&!"".equals(videoId.trim())){
+                    setCreative.put("videoId",videoId);
+                    setCreative.put("videoUrl","https://aweme.snssdk.com/aweme/v1/playwm/?video_id="+videoId+"&line=0");
+                }
+                String thirdPartyId = getCreative.getString("third_party_id");
+                if(null!=thirdPartyId&&!"".equals(thirdPartyId.trim())){
+                    setCreative.put("thirdPartyId",thirdPartyId);
+                }
+                Long derivePosterCid = getCreative.getLong("derive_poster_cid");
+                if(null!=derivePosterCid){
+                    setCreative.put("derivePosterCid",derivePosterCid);
+                }
+                Integer templateId = getCreative.getInteger("template_id");
+                if(null!=templateId){
+                    setCreative.put("templateId",templateId);
+                }
+                String templateImageId = getCreative.getString("template_image_id");
+                if(null!=templateImageId&&!"".equals(templateImageId.trim())){
+                    setCreative.put("templateImageId",templateImageId);
+                }
+                Long dpaTemplate = getCreative.getLong("dpa_template");
+                if(null!=dpaTemplate){
+                    setCreative.put("dpaTemplate",dpaTemplate);
+                }
+                String dpaVideoTemplateType = getCreative.getString("dpa_video_template_type");
+                if(null!=dpaVideoTemplateType&&!"".equals(dpaVideoTemplateType.trim())){
+                    setCreative.put("dpaVideoTemplateType",dpaVideoTemplateType);
+                }
+                JSONArray dpaVideoTaskIds = getCreative.getJSONArray("dpa_video_task_ids");
+                if(null!=dpaVideoTaskIds&&!dpaVideoTaskIds.isEmpty()){
+                    setCreative.put("dpaVideoTaskIds",dpaVideoTaskIds);
+                }
+                creativeArray.add(setCreative);
+            }
+            data.put("creatives",creativeArray);
+        }
+
+        return data;
+    }
+
+    /**
+     * @param data
+     * @return
+     */
+    @Override
+    public Map<String,Object> updateCreative(JSONObject data){
+        log.info(data.toJSONString());
+        Map<String,Object>result = new HashMap<>();
+        Long accountId = data.getLong("accountId");
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        if(null == token){
+            ResultMapUtils.setResultMap(result, StatusCode.COMMON_PARAM_ERROR);
+            return result;
+        }
+        JSONArray planIdArray = data.getJSONArray("adIds");
+        if(null == planIdArray||planIdArray.isEmpty()){
+            ResultMapUtils.setResultMap(result,StatusCode.COMMON_PARAM_ERROR);
+            return result;
+        }
+        data.remove("adIds");
+        data.put("adId",planIdArray.getLong(0));
+        JSONObject detail = (JSONObject) this.getCreativeDetail(token,planIdArray.getLong(0)).get("data");
+        String modifyTime = detail.getString("modifyTime");
+        data.put("modifyTime",modifyTime);
+        JSONObject params = initParams(data);
+        JSONArray array = new JSONArray();
+        Map<String,Object> getData = updateCreative(token,params,planIdArray.getLong(0));
+        array.add(getData);
+        result.put("data",array);
+        ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS);
+        return result;
+    }
+
+    public Map<String,Object>updateCreative(CtopOauthToken token,JSONObject params,Long adId){
+        Map<String, Object> result = new HashMap<>();
+        // 请求地址
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_update");
+        JSONObject dataObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),url,params);
+        Integer code = dataObject.getInteger("code");
+        String message = dataObject.getString("message");
+        if (null == code || code != 0) {
+            log.info("广告创意更新失败,accountId:{},message:{}", token.getAccountId(), message);
+            result.put("success", false);
+            result.put("code", -1);
+            result.put("message", message);
+            return result;
+        }
+        Thread thread = new Thread(()->getAdvertiserCreative(token,null, DateUtils.formatDate()));
+        thread.start();
+        result.put("success", true);
+        result.put("code", 0);
+        result.put("message", "广告计划("+adId+"):"+"创意更新成功");
+        return result;
+    }
+
+    @Override
+    public Map<String,Object> getCreativeRejectReason(Long accountId, Long creativeId){
+        Map<String,Object>resultMap = new HashMap<>();
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        JSONArray creativeIds = new JSONArray();
+        creativeIds.add(creativeId);
+        // 请求地址
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_reject_reason");
+        // 请求参数
+        JSONObject data = new JSONObject();
+        data.put("advertiser_id", accountId);
+        data.put("creative_ids", creativeIds);
+        JSONObject result = HttpUtils.bytedancePostRequest(token.getAccessToken(),url,data);
+        Integer code = result.getInteger("code");
+        String message = result.getString("message");
+        if (null == code || code != 0) {
+            log.info("广告创意创意审核建议获取失败,accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", message);
+            return resultMap;
+        }
+        resultMap.put("data",result.getJSONObject("data"));
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS);
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> batchCreate(JSONObject data) {
+        log.info(data.toJSONString());
+        Map<String,Object>result = new HashMap<>();
+        Long accountId = data.getLong("accountId");
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        if(null == token){
+            ResultMapUtils.setResultMap(result,StatusCode.COMMON_PARAM_ERROR);
+            return result;
+        }
+        JSONArray planIds = data.getJSONArray("adIds");
+        if(null == planIds||planIds.isEmpty()){
+            ResultMapUtils.setResultMap(result,StatusCode.COMMON_PARAM_ERROR);
+            return result;
+        }
+        //拼接参数
+        JSONObject params  = initParams(data);
+        JSONArray array = new JSONArray();
+        for(int i=0;i<planIds.size();i++){
+            Map<String,Object> getData = creativeCreate(accountId+"",planIds.getLong(i),params);
+            array.add(getData);
+        }
+        Thread thread = new Thread(()->getAdvertiserCreative(token,null, DateUtils.formatDate()));
+        thread.start();
+        result.put("data",array);
+        ResultMapUtils.setResultMap(result,StatusCode.COMMON_SUCCESS);
+        return result;
+    }
+
+
+    private JSONObject initParams(JSONObject data) {
+        JSONObject params = new JSONObject();
+        String creativeWay = data.getString("creativeWay");
+        params.put("advertiser_id",data.getLong("accountId"));
+        Long adId = data.getLong("adId");
+        if(null!=adId&&adId!=0){
+            params.put("ad_id",adId);
+        }
+        String modifyTime = data.getString("modifyTime");
+        params.put("modify_time",modifyTime);
+        //###############公共参数开始################################
+        //优选广告位
+        Integer smartInventory = data.getInteger("smartInventory");
+        if(null!=smartInventory){
+            params.put("smart_inventory",smartInventory);
+        }
+        //媒体指定位置
+        JSONArray inventoryType = data.getJSONArray("inventoryType");
+        if(null!=inventoryType){
+            params.put("inventory_type",inventoryType);
+        }
+        //场景指定位置
+        String sceneInventory = data.getString("sceneInventory");
+        if(null!=sceneInventory&&!"".equals(sceneInventory.trim())){
+            params.put("scene_inventory",sceneInventory);
+        }
+        JSONArray adKeywords = data.getJSONArray("adKeywords");
+        if(null!=adKeywords&&!adKeywords.isEmpty()){
+            params.put("ad_keywords",adKeywords);
+        }
+        Long thirdIndustryId = data.getLong("thirdIndustryId");
+        if(null!=thirdIndustryId&&thirdIndustryId!=0){
+            params.put("third_industry_id",thirdIndustryId);
+        }
+
+        /**
+         * 创意展现方式
+         */
+        String creativeDisplayMode = data.getString("creativeDisplayMode");
+        if(null!=creativeDisplayMode&& "".equals(creativeDisplayMode.trim())){
+            params.put("creative_display_mode",creativeDisplayMode);
+        }
+        String trackUrl = data.getString("trackUrl");
+        if(null!=trackUrl&& "".equals(trackUrl.trim())){
+            params.put("track_url",trackUrl);
+        }
+        String actionTrackUrl = data.getString("actionTrackUrl");
+        if(null!=actionTrackUrl&& "".equals(actionTrackUrl.trim())){
+            params.put("action_track_url",actionTrackUrl);
+        }
+        String videoPlayEffectiveTrackUrl = data.getString("videoPlayEffectiveTrackUrl");
+        if(null!=videoPlayEffectiveTrackUrl&& "".equals(videoPlayEffectiveTrackUrl.trim())){
+            params.put("video_play_effective_track_url",videoPlayEffectiveTrackUrl);
+        }
+        String videoPlayDoneTrackUrl = data.getString("videoPlayDoneTrackUrl");
+        if(null!=videoPlayDoneTrackUrl&& "".equals(videoPlayDoneTrackUrl.trim())){
+            params.put("video_play_done_track_url",videoPlayDoneTrackUrl);
+        }
+        String videoPlayTrackUrl = data.getString("videoPlayTrackUrl");
+        if(null!=videoPlayTrackUrl&& "".equals(videoPlayTrackUrl.trim())){
+            params.put("video_play_track_url",videoPlayTrackUrl);
+        }
+        Long isCommentDisable = data.getLong("isCommentDisable");
+        if(null!=isCommentDisable&&isCommentDisable!=0){
+            params.put("is_comment_disable",isCommentDisable);
+        }
+        Long closeVideoDetail = data.getLong("closeVideoDetail");
+        if(null!=closeVideoDetail){
+            params.put("close_video_detail",closeVideoDetail);
+        }
+        Long generateDerivedAd = data.getLong("generateDerivedAd");
+        if(null!=generateDerivedAd&&generateDerivedAd!=0){
+            params.put("generate_derived_ad",generateDerivedAd);
+        }
+        String playableUrl = data.getString("playableUrl");
+        if(null!=playableUrl&&!"".equals(playableUrl.trim())){
+            params.put("playable_url",playableUrl);
+        }
+        Long isPresentedVideo = data.getLong("isPresentedVideo");
+        if(null!=isPresentedVideo&&isPresentedVideo!=0){
+            params.put("is_presented_video",isPresentedVideo);
+        }
+        Long creativeAutoGenerateSwitch = data.getLong("creativeAutoGenerateSwitch");
+        if(null!=creativeAutoGenerateSwitch&&creativeAutoGenerateSwitch!=0){
+            params.put("creative_auto_generate_switch",creativeAutoGenerateSwitch);
+        }
+        String trackUrlSendType = data.getString("trackUrlSendType");
+        if(null!=trackUrlSendType&&!"".equals(trackUrlSendType.trim())){
+            params.put("track_url_send_type",trackUrlSendType);
+        }
+        String iesCoreUserId = data.getString("iesCoreUserId");
+        if(null!=iesCoreUserId&&!"".equals(iesCoreUserId)){
+            params.put("ies_core_user_id",iesCoreUserId);
+        }
+        Long isFeedAndFavSee = data.getLong("isFeedAndFavSee");
+        if(null!=isFeedAndFavSee&&isFeedAndFavSee!=0){
+            params.put("is_feed_and_fav_see",isFeedAndFavSee);
+        }
+        JSONArray subLinkIdList = data.getJSONArray("subLinkIdList");
+        if(null!=subLinkIdList&&!subLinkIdList.isEmpty()){
+            params.put("sub_link_id_list",subLinkIdList);
+        }
+
+        String source = data.getString("source");
+        if(null!=source&&!"".equals(source.trim())){
+            params.put("source",source);
+        }
+        //###############公共参数结束################################
+
+        //#######推广目的为APP######################################
+        String appName = data.getString("appName");
+        if(null!=appName&&!"".equals(appName.trim())){
+            params.put("app_name",appName);
+        }
+        String webUrl = data.getString("webUrl");
+        if(null!=webUrl&&!"".equals(webUrl.trim())){
+            params.put("web_url",webUrl);
+        }
+        String actionText = data.getString("actionText");
+        if(null!=actionText&&!"".equals(actionText.trim())){
+            params.put("action_text",actionText);
+        }
+        String subTitle = data.getString("subTitle");
+        if(null!=subTitle&&!"".equals(subTitle.trim())){
+            params.put("sub_title",subTitle);
+        }
+        //###############################################
+        //############创意推广目的为link的时候###################
+        String advancedCreativeType = data.getString("advancedCreativeType");
+        if(null!=advancedCreativeType&&!"".equals(advancedCreativeType.trim())){
+            params.put("advanced_creative_type",advancedCreativeType);
+        }
+        String advancedCreativeTitle = data.getString("advancedCreativeTitle");
+        if(null!=advancedCreativeTitle&&!"".equals(advancedCreativeTitle.trim())){
+            params.put("advanced_creative_title",advancedCreativeTitle);
+        }
+        String phoneNumber = data.getString("phoneNumber");
+        if(null!=phoneNumber&&!"".equals(phoneNumber.trim())){
+            params.put("phone_number",phoneNumber);
+        }
+        String buttonText = data.getString("buttonText");
+        if(null!=buttonText&&!"".equals(buttonText.trim())){
+            params.put("button_text",buttonText);
+        }
+        String formUrl = data.getString("formUrl");
+        if(null!=formUrl&&!"".equals(formUrl.trim())){
+            params.put("form_url",formUrl);
+        }
+
+        if(null!=creativeWay&& "proceduralCreativity".equals(creativeWay.trim())){
+            //程序化
+            params.put("creative_material_mode","STATIC_ASSEMBLE");
+            JSONArray titleList = data.getJSONArray("titleList");
+            if(null!=titleList&&!titleList.isEmpty()){
+                JSONArray setTitleList = new JSONArray();
+                for (int i=0;i<titleList.size();i++){
+                    JSONObject titleObject = titleList.getJSONObject(i);
+                    JSONArray creativeWordIds = titleObject.getJSONArray("creativeWordIds");
+                    titleObject.remove("creativeWordIds");
+                    if(null!=creativeWordIds&&!creativeWordIds.isEmpty()){
+                        titleObject.put("creative_word_ids",creativeWordIds);
+                    }
+                    setTitleList.add(titleObject);
+                }
+                params.put("title_list",setTitleList);
+            }
+            JSONArray imageList = data.getJSONArray("imageList");
+            if(null!=imageList&&!imageList.isEmpty()){
+                JSONArray setImageList = new JSONArray();
+                for (int i=0;i<imageList.size();i++){
+                    JSONObject imageObject = imageList.getJSONObject(i);
+                    String imageMode = imageObject.getString("imageMode");
+                    JSONArray imageIds = imageObject.getJSONArray("imageIds");
+                    String imageId = imageObject.getString("imageId");
+                    String videoId = imageObject.getString("videoId");
+                    Integer templateId = imageObject.getInteger("templateId");
+                    imageObject.remove("imageMode");
+                    imageObject.remove("imageIds");
+                    imageObject.remove("imageId");
+                    imageObject.remove("videoId");
+                    imageObject.remove("templateId");
+                    imageObject.put("image_mode",imageMode);
+                    if(null!=imageIds&&!imageIds.isEmpty()){
+                        imageObject.put("image_ids",imageIds);
+                    }
+                    if(null!=imageId&&!"".equals(imageId.trim())){
+                        imageObject.put("image_id",imageId);
+                    }
+                    if(null!=videoId&&!"".equals(videoId.trim())){
+                        imageObject.put("video_id",videoId);
+                    }
+                    if(null!=templateId&&templateId!=0){
+                        imageObject.put("template_id",templateId);
+                    }
+
+                    setImageList.add(imageObject);
+                }
+                params.put("image_list",setImageList);
+            }
+        }else{
+            //自定义创意
+            JSONArray creatives = data.getJSONArray("creatives");
+            if(null!=creatives&&!creatives.isEmpty()){
+                JSONArray setCreatives = new JSONArray();
+                for(int i=0;i<creatives.size();i++){
+                    JSONObject creativeObject = creatives.getJSONObject(i);
+                    JSONArray creativeWordIds = creativeObject.getJSONArray("creativeWordIds");
+                    creativeObject.remove("creativeWordIds");
+                    if(null!=creativeWordIds&&!creativeWordIds.isEmpty()){
+                        creativeObject.put("creative_word_ids",creativeWordIds);
+                    }
+                    String imageMode = creativeObject.getString("imageMode");
+                    creativeObject.remove("imageMode");
+                    creativeObject.put("image_mode",imageMode);
+                    JSONArray imageIds = creativeObject.getJSONArray("imageIds");
+                    creativeObject.remove("imageIds");
+                    if(null!=imageIds&&!imageIds.isEmpty()){
+                        creativeObject.put("image_ids",imageIds);
+                    }
+                    String imageId = creativeObject.getString("imageId");
+                    creativeObject.remove("imageId");
+                    if(null!=imageId&&!"".equals(imageId.trim())){
+                        creativeObject.put("image_id",imageId);
+                    }
+                    String videoId = creativeObject.getString("videoId");
+                    creativeObject.remove("videoId");
+                    if(null!=videoId&&!"".equals(videoId.trim())){
+                        creativeObject.put("video_id",videoId);
+                    }
+                    Integer templateId = creativeObject.getInteger("templateId");
+                    creativeObject.remove("templateId");
+                    if(null!=templateId&&templateId!=0){
+                        creativeObject.put("template_id",templateId);
+                    }
+                    JSONArray dpaDictIds = creativeObject.getJSONArray("dpaDictIds");
+                    creativeObject.remove("dpaDictIds");
+                    if(null!=dpaDictIds&&!dpaDictIds.isEmpty()){
+                        creativeObject.put("dpa_dict_ids",dpaDictIds);
+                    }
+//                    String text = creativeObject.getString("title");
+//                    creativeObject.remove("text");
+//                    if(null!=text&&!"".equals(text.trim())){
+//                        creativeObject.put("title",text);
+//                    }
+                    Integer derivePosterCid = creativeObject.getInteger("derivePosterCid");
+                    creativeObject.remove("derivePosterCid");
+                    if(null!=derivePosterCid&&derivePosterCid!=0){
+                        creativeObject.put("derive_poster_cid",derivePosterCid);
+                    }
+                    setCreatives.add(creativeObject);
+                }
+                params.put("creatives",setCreatives);
+            }
+        }
+        return params;
+    }
+}

+ 44 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceVideoInfoServiceImpl.java

@@ -0,0 +1,44 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo;
+import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceVideoInfoMapper;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceVideoInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Description: 今日头条视频素材信息
+ * @Author: jeecg-boot
+ * @Date: 2019-07-29
+ * @Version: V1.0
+ */
+@Service
+@Primary
+public class ByteDanceVideoInfoServiceImpl extends ServiceImpl<ByteDanceVideoInfoMapper, ByteDanceVideoInfo> implements IByteDanceVideoInfoService {
+    @Autowired
+    private ByteDanceVideoInfoMapper videoInfoMapper;
+
+    @Override
+    public void replaceBatch(List<ByteDanceVideoInfo> videoInfoList) {
+        videoInfoMapper.replaceBatch(videoInfoList);
+    }
+
+    @Override
+    public ByteDanceVideoInfo getOneByParams(Long materialId) {
+        QueryWrapper<ByteDanceVideoInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("material_id",materialId);
+        queryWrapper.last("limit 1");
+        return this.getOne(queryWrapper);
+    }
+
+    @Override
+    public void updateMaterialType() {
+        videoInfoMapper.updateVideoVerticalType();
+        videoInfoMapper.updateVideoHorizonType();
+    }
+}

+ 32 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/BytedanceImageInfoServiceImpl.java

@@ -0,0 +1,32 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.bytedance.advertise.entity.BytedanceImageInfo;
+import org.jeecg.modules.bytedance.advertise.mapper.BytedanceImageInfoMapper;
+import org.jeecg.modules.bytedance.advertise.service.IBytedanceImageInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 头条图片素材
+ * @author jeecg-boot
+ * @date   2020-08-01
+ * @version V1.0
+ */
+@Service
+public class BytedanceImageInfoServiceImpl extends ServiceImpl<BytedanceImageInfoMapper, BytedanceImageInfo> implements IBytedanceImageInfoService {
+    @Autowired
+    private BytedanceImageInfoMapper imageInfoMapper;
+    @Override
+    public void replaceBatch(List<BytedanceImageInfo> videoInfoList) {
+        imageInfoMapper.replaceBatch(videoInfoList);
+    }
+
+    @Override
+    public void updateType() {
+        imageInfoMapper.updateImageVerticalType();
+        imageInfoMapper.updateImageHorizonType();
+    }
+}

+ 12 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/vo/BytedanceCampaignEditVo.java

@@ -0,0 +1,12 @@
+package org.jeecg.modules.bytedance.advertise.vo;
+
+import lombok.Data;
+
+@Data
+public class BytedanceCampaignEditVo {
+    private Long accountId;
+    private Long id;
+    private String campaignName;
+    private String budgetMode;
+    private Integer budget;
+}

+ 15 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/vo/BytedanceVideoVo.java

@@ -0,0 +1,15 @@
+package org.jeecg.modules.bytedance.advertise.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author 宋英豪
+ */
+@Data
+public class BytedanceVideoVo implements Serializable {
+    private String code;
+    private String url;
+    private String initialCostDate;
+}

+ 4 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/aa.java

@@ -0,0 +1,4 @@
+package org.jeecg.modules.bytedance.common;
+
+public class aa {
+}

+ 136 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/entity/CtopOauthToken.java

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

+ 59 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/CtopOauthTokenMapper.java

@@ -0,0 +1,59 @@
+package org.jeecg.modules.bytedance.common.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+
+import java.util.List;
+
+/**
+ * oauth授权码
+ * @author jeecg-boot
+ * 2019-07-09
+ * @version V1.0
+ */
+public interface CtopOauthTokenMapper extends BaseMapper<CtopOauthToken> {
+    /**
+     * 更新
+     *
+     * @param oauthToken 授权信息
+     * @return i
+     */
+    int updateByPrimaryKeySelective(CtopOauthToken oauthToken);
+
+    /**
+     * 根据accountId查询
+     *
+     * @param accountId 账户id
+     * @return token
+     */
+    CtopOauthToken selectByAccountId(Long accountId);
+
+    List<CtopOauthToken> selectKuaiShouToken();
+
+    List<CtopOauthToken> selectKuaiShouTokenBefore();
+
+    List<CtopOauthToken> selectToutiaoToken();
+
+    CtopOauthToken getAccessTokenByAccountIdAndMediaId(@Param("mediaId") Integer mediaId, @Param("accountId") Long accountId);
+
+    List<CtopOauthToken> getToutiaoTokenByCreateTime(@Param("createTime") String createTime);
+
+    /**
+     * 查询头条token
+     *
+     * @param platformTypeByteDance
+     * @return
+     */
+    List<CtopOauthToken> selectByteDanceTokens(@Param("mediaId") String platformTypeByteDance);
+
+
+    /**
+     * 查询头条token
+     *
+     * @param platformTypeByteDance
+     * @return
+     */
+    List<CtopOauthToken> selectKuaiShouTokens(@Param("mediaId") String platformTypeByteDance);
+
+}

+ 139 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/mapper/xml/CtopOauthTokenMapper.xml

@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.com.ctop.common.module.mapper.CtopOauthTokenMapper">
+
+    <resultMap id="BaseResultMap" type="cn.com.ctop.common.module.entity.CtopOauthToken">
+        <result column="id" property="id" jdbcType="BIGINT"/>
+        <result column="media_id" property="mediaId" jdbcType="VARCHAR"/>
+        <result column="advertiser_id" property="advertiserId" jdbcType="VARCHAR"/>
+        <result column="account_id" property="accountId" jdbcType="BIGINT"/>
+        <result column="access_token" property="accessToken" jdbcType="VARCHAR"/>
+        <result column="refresh_token" property="refreshToken" jdbcType="VARCHAR"/>
+        <result column="access_token_expires_in" property="accessTokenExpiresIn" jdbcType="TIMESTAMP"/>
+        <result column="refresh_token_expires_in" property="refreshTokenExpiresIn" jdbcType="TIMESTAMP"/>
+        <result column="agent_type" property="agentType" jdbcType="INTEGER"/>
+        <result column="app_id" property="appId" jdbcType="BIGINT"/>
+        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
+        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,media_id,advertiser_id,account_id,access_token,refresh_token,access_token_expires_in,refresh_token_expires_in,agent_type,app_id,create_time,update_time
+   </sql>
+
+    <select id="selectByteDanceTokens" resultMap="BaseResultMap">
+        select
+        <include refid="Base_Column_List"/>
+        from ctop_oauth_token
+        where media_id = #{mediaId}
+        group by access_token
+    </select>
+
+    <select id="selectKuaiShouTokens" resultMap="BaseResultMap">
+        select
+        <include refid="Base_Column_List"/>
+        from ctop_oauth_token
+        where media_id = #{mediaId}
+        group by account_id
+    </select>
+
+
+    <update id="updateByPrimaryKeySelective" parameterType="cn.com.ctop.common.module.entity.CtopOauthToken">
+        update ctop_oauth_token
+        <set>
+
+            <if test="mediaId != null">
+                media_id = #{mediaId},
+            </if>
+
+            <if test="advertiserId != null">
+                advertiser_id = #{advertiserId},
+            </if>
+
+            <if test="accessToken != null">
+                access_token = #{accessToken},
+            </if>
+
+            <if test="accessTokenExpiresIn != null">
+                access_token_expires_in = #{accessTokenExpiresIn},
+            </if>
+
+            <if test="refreshToken != null">
+                refresh_token = #{refreshToken,jdbcType=VARCHAR},
+            </if>
+
+            <if test="refreshTokenExpiresIn != null">
+                refresh_token_expires_in = #{refreshTokenExpiresIn},
+            </if>
+
+            <if test="createTime != null">
+                create_time = #{createTime},
+            </if>
+
+            <if test="updateTime != null">
+                update_time = #{updateTime},
+            </if>
+        </set>
+        where account_id = #{accountId}
+    </update>
+
+    <select id="selectByAccountId" resultMap="BaseResultMap">
+        select
+        <include refid="Base_Column_List"/>
+        from ctop_oauth_token
+        where account_id = #{accountId}
+        order by create_time desc
+        limit 1
+    </select>
+
+
+    <select id="selectKuaiShouToken" resultType="cn.com.ctop.common.module.entity.CtopOauthToken">
+        select  t1.*
+        from ctop_oauth_token t1
+        left join ctop_user_allocation t2
+        on t1.account_id = t2.account_id
+        where t2.account_status = 0
+        and t1.media_id = 2
+
+    </select>
+
+    <select id="selectKuaiShouTokenBefore" resultType="cn.com.ctop.common.module.entity.CtopOauthToken">
+        select  t1.*
+        from ctop_oauth_token t1
+        left join ctop_user_allocation t2
+        on t1.account_id = t2.account_id
+        where t1.media_id = 2
+        and date_format(t2.create_time, '%Y-%m-%d') = date_sub(curdate(),interval 1 day)
+    </select>
+
+    <select id="selectToutiaoToken" resultType="cn.com.ctop.common.module.entity.CtopOauthToken">
+        select t1.*
+        from ctop_oauth_token t1
+        left join ctop_user_allocation t2
+        on t1.account_id = t2.account_id
+        where t1.media_id in (1,3) and t2.account_status = 0
+        group by account_id
+    </select>
+
+    <select id="getAccessTokenByAccountIdAndMediaId" resultType="cn.com.ctop.common.module.entity.CtopOauthToken">
+        select
+        *
+        from
+        ctop_oauth_token
+        where media_id = #{mediaId}
+        and account_id = #{accountId}
+    </select>
+
+    <!-- 根据mediaType 和 账户绑定助手时间createTime 获取accountId -->
+    <select id="getToutiaoTokenByCreateTime" resultType="cn.com.ctop.common.module.entity.CtopOauthToken">
+            select t1.*
+        from ctop_oauth_token t1
+        left join ctop_user_allocation t2
+        on t1.account_id = t2.account_id
+        where t2.account_status = 0
+        and t1.media_id in (1,3)
+        and date_format(t2.create_time, '%Y-%m-%d') = #{createTime}
+        group by account_id
+    </select>
+
+</mapper>

+ 35 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/ICtopOauthTokenService.java

@@ -0,0 +1,35 @@
+package org.jeecg.modules.bytedance.common.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: oauth授权码
+ * @Author: jeecg-boot
+ * @Date: 2019-07-09
+ * @Version: V1.0
+ */
+public interface ICtopOauthTokenService extends IService<CtopOauthToken> {
+
+    CtopOauthToken getOauthTokenByAccountId(String accountId);
+
+    CtopOauthToken getTokenByAccountId(Long accountId);
+
+    Map<String, Object> getByteDanceAccessToken(CtopOauthToken token);
+
+
+    List<CtopOauthToken> getTokenListByType(String platformTypeBytedance);
+
+    List<CtopOauthToken> selectToutiaoToken();
+
+    CtopOauthToken getAccessTokenByAccountIdAndMediaId(Integer mediaId, Long accountId);
+
+    List<CtopOauthToken> getToutiaoTokenByCreateTime(String createTime);
+
+    List<CtopOauthToken> getByProjectId(Long projectId);
+
+    CtopOauthToken selectOneByMediaId(String platformTypeKuaishou);
+}

+ 166 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/CtopOauthTokenServiceImpl.java

@@ -0,0 +1,166 @@
+package org.jeecg.modules.bytedance.common.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.mapper.CtopOauthTokenMapper;
+import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
+import org.jeecg.modules.bytedance.common.utils.HttpUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: oauth授权码
+ * @Author: jeecg-boot
+ * @Date: 2019-07-09
+ * @Version: V1.0
+ */
+@Slf4j
+@Service
+public class CtopOauthTokenServiceImpl extends ServiceImpl<CtopOauthTokenMapper, CtopOauthToken> implements ICtopOauthTokenService {
+    @Value("${bytedance.appId}")
+    private String bytedanceAppId;
+    @Value("${bytedance.secret}")
+    private String bytedanceSecret;
+    @Value("${bytedance.url.api-prefix}")
+    private String bytedanceUrlApiPrefix;
+    @Value("${bytedance.url.refresh-token}")
+    private String bytedanceUrlRefreshToken;
+    @Value("${kuaishou.api-url}")
+    private String kuaishouApiUrl;
+
+    @Resource
+    private CtopOauthTokenMapper ctopOauthTokenMapper;
+
+    @Override
+    public CtopOauthToken getOauthTokenByAccountId(String accountId) {
+        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id", accountId).orderByDesc("create_time");
+        queryWrapper.last("limit 1");
+        return this.getOne(queryWrapper);
+    }
+
+
+    @Override
+    public CtopOauthToken getTokenByAccountId(Long accountId) {
+        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id", accountId).orderByDesc("create_time");
+        queryWrapper.last("limit 1");
+        return this.getOne(queryWrapper);
+    }
+
+    /**
+     * 刷新token
+     *
+     * @return
+     */
+    @Override
+    public Map<String, Object> getByteDanceAccessToken(CtopOauthToken token) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String url = bytedanceUrlApiPrefix + bytedanceUrlRefreshToken;
+        Map<String, Object> param = new HashMap<>();
+        param.put("app_id", bytedanceAppId);
+        param.put("secret", bytedanceSecret);
+        param.put("grant_type", "refresh_token");
+        param.put("refresh_token", token.getRefreshToken());
+        String result = HttpUtils.httpPostRequest(url, param, new HashMap<>());
+        System.err.println(JSONObject.parseObject(result));
+        log.info("头条刷新token;accountId:{},返回信息:{}", token.getAccountId(), result);
+        if (null == result || "".equals(result.trim()) || "null".equalsIgnoreCase(result)) {
+            log.info("头条刷新token失败;accountId:{},返回信息:{}", token.getAccountId(), result);
+            resultMap.put("message", "token刷新失败");
+            resultMap.put("token", token);
+            resultMap.put("code", 0);
+            return resultMap;
+        }
+        JSONObject resultObject = JSONObject.parseObject(result);
+        Integer code = resultObject.getInteger("code");
+        String message = resultObject.getString("message");
+        if (code == 0) {
+            JSONObject data = resultObject.getJSONObject("data");
+            CtopOauthToken updateRefreshToken = new CtopOauthToken();
+            updateRefreshToken.setAccessToken(data.getString("access_token"));
+            updateRefreshToken.setRefreshToken(data.getString("refresh_token"));
+            Date now = new Date();
+            Integer refreshTokenExpiresIn = data.getInteger("refresh_token_expires_in");
+            Integer expiresIn = data.getInteger("expires_in");
+            updateRefreshToken.setRefreshTokenExpiresIn(DateUtils.addSecond(now, refreshTokenExpiresIn));
+            updateRefreshToken.setAccessTokenExpiresIn(DateUtils.addSecond(now, expiresIn));
+            QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("access_token", token.getAccessToken());
+            queryWrapper.eq("media_id", 1);
+            int i = ctopOauthTokenMapper.update(updateRefreshToken, queryWrapper);
+            if (i > 0) {
+                log.info("头条刷新token成功:accountId:{}", token.getAccountId());
+            }
+            resultMap.put("message", "token刷新成功");
+            resultMap.put("code", 0);
+        } else {
+            log.info("头条刷新token失败;accountId:{},返回信息:{}", token.getAccountId(), message);
+            resultMap.put("message", message);
+            resultMap.put("token", token);
+            resultMap.put("code", 0);
+        }
+        return resultMap;
+    }
+
+
+
+    @Override
+    public List<CtopOauthToken> getTokenListByType(String platformType) {
+        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
+        if (null != platformType && !"".equals(platformType.trim())) {
+            queryWrapper.eq("media_id", platformType);
+        }
+        queryWrapper.orderByDesc("account_id");
+        return this.list(queryWrapper);
+    }
+
+
+    /**
+     * 获取toutiao有效账户列表
+     *
+     * @return
+     */
+
+    @Override
+    public List<CtopOauthToken> selectToutiaoToken() {
+        return ctopOauthTokenMapper.selectToutiaoToken();
+    }
+
+
+    @Override
+    public CtopOauthToken getAccessTokenByAccountIdAndMediaId(Integer mediaId, Long accountId) {
+        return ctopOauthTokenMapper.getAccessTokenByAccountIdAndMediaId(mediaId, accountId);
+    }
+
+    @Override
+    public List<CtopOauthToken> getToutiaoTokenByCreateTime(String createTime) {
+        return ctopOauthTokenMapper.getToutiaoTokenByCreateTime(createTime);
+    }
+
+    @Override
+    public List<CtopOauthToken> getByProjectId(Long projectId) {
+        QueryWrapper<CtopOauthToken> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("project_id", projectId).eq("account_status", 0);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public CtopOauthToken selectOneByMediaId(String platformTypeKuaishou) {
+        QueryWrapper<CtopOauthToken> tokenQueryWrapper = new QueryWrapper<>();
+        tokenQueryWrapper.eq("media_id", platformTypeKuaishou);
+        tokenQueryWrapper.orderByDesc("create_time");
+        tokenQueryWrapper.last("limit 1");
+        return this.getOne(tokenQueryWrapper);
+    }
+}

+ 66 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/Check.java

@@ -0,0 +1,66 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class Check {
+    private Check() {
+    }
+
+    public static boolean isNull(List<?> list) {
+        return list == null || list.isEmpty();
+    }
+
+    public static boolean isNull(Long l) {
+        return l == null || l == 0;
+    }
+
+    public static boolean isNull(Collection<?> collection) {
+        return collection == null || collection.isEmpty();
+    }
+
+    public static boolean isNull(JSONArray jsonArray) {
+        return jsonArray == null || jsonArray.isEmpty();
+    }
+
+
+    public static boolean isNull(String str) {
+        return str == null || str.isEmpty();
+    }
+
+    public static boolean isNull(byte[] bytes) {
+        return bytes == null || bytes.length == 0;
+    }
+
+    public static boolean hasNull(Object... objects) {
+        for (Object obj : objects) {
+            if (obj == null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean allEmpty(String... strs) {
+        for (String str : strs) {
+            if (StringUtils.isNotEmpty(str)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isNull(Object object) {
+        return object == null;
+    }
+
+    public static boolean isNullMap(Map<?, ?> map) {
+        return map == null || map.isEmpty();
+    }
+}

+ 1 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/utils/CtopAdConstant.java

@@ -1,4 +1,4 @@
-package org.jeecg.modules.bytedance.advertise.utils;
+package org.jeecg.modules.bytedance.common.utils;
 
 import java.math.BigDecimal;
 

+ 28 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/HttpGetWithBodyEntity.java

@@ -0,0 +1,28 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+
+import java.net.URI;
+
+public class HttpGetWithBodyEntity extends HttpEntityEnclosingRequestBase {
+    private final static String METHOD_NAME = "GET";
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+
+    public HttpGetWithBodyEntity() {
+        super();
+    }
+
+    public HttpGetWithBodyEntity(final URI uri) {
+        super();
+        setURI(uri);
+    }
+
+    HttpGetWithBodyEntity(final String uri) {
+        super();
+        setURI(URI.create(uri));
+    }
+}

+ 955 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/HttpUtils.java

@@ -0,0 +1,955 @@
+package org.jeecg.modules.bytedance.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.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 void main(String[] args) {
+        String res = HttpUtils.getKuaishouShareUrl("http://yongzhou.s.gifshow.com/i/photo/lwx?userId=1400097524&photoId=5191805968879099278");
+        String path = res.split("\\?")[0];
+        String photoId = path.substring(path.lastIndexOf("/") + 1, path.length());
+        path = path.substring(0, path.lastIndexOf("/"));
+        String uid = path.substring(path.lastIndexOf("/") + 1, path.length());
+
+        res = HttpUtils.postKuaishouVideoUrl("https://live.kuaishou.com/m_graphql", uid, photoId);
+    }
+
+    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();
+        return HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
+    }
+
+    public static String callingGraph(String url, String json) {
+        HttpClient httpClient = createSslClientDefault();
+        HttpResponse response = null;
+        HttpPost httpPost = new HttpPost(url);
+        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("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 = URLEncoder.encode((String) 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, "&");
+            System.err.println(uri);
+            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 httpGetRequest(String url, Map<String, String> headers, JSONObject params) {
+        HttpClient httpClient = createSslClientDefault();
+        String strReturn = "";
+        try {
+            HttpGetWithBodyEntity httpGet = new HttpGetWithBodyEntity(url);
+            if (headers != null) {
+                Iterator<String> keyIter = headers.keySet().iterator();
+                while (keyIter.hasNext()) {
+                    String curKey = keyIter.next();
+                    if (curKey != null && headers.get(curKey) != null) {
+                        httpGet.addHeader(curKey, headers.get(curKey));
+                    }
+                }
+            }
+            httpGet.setEntity(new StringEntity(params.toJSONString(), Charset.forName("UTF-8")));
+            HttpEntity respentity;
+            HttpResponse response = httpClient.execute(httpGet);
+            respentity = response.getEntity();
+            strReturn = EntityUtils.toString(respentity);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+
+    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;
+    }
+}

+ 64 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/PropertiesUtils.java

@@ -0,0 +1,64 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author jeecg-boot
+ * 2019年11月12日10:04:00
+ */
+public class PropertiesUtils {
+    private static final Logger log = LoggerFactory.getLogger(PropertiesUtils.class);
+    private static Map<String, String> cache = new HashMap<>();
+    public static String getConfig(String key) {
+        return getValue("kuaishou_config", key);
+    }
+    public static String getValue(String name, String key) {
+        try {
+            String cacheValue = cache.get(name + key);
+            if (cacheValue != null) {
+                return cacheValue;
+            }
+            Properties props = new Properties();
+            InputStream in = PropertiesUtils.class.getResourceAsStream("/"
+                    + name + ".properties");
+            props.load(in);
+            String value = props.getProperty(key);
+            cache.put(name + key, value);
+            props.clone();
+            in.close();
+            return value;
+        } catch (Exception e) {
+            log.error("PropertiesUtil getCacheValue Error", e);
+        }
+        return null;
+    }
+
+    public static Map<String, String> getMap(String name) {
+        try {
+            Properties props = new Properties();
+            InputStream in = PropertiesUtils.class.getResourceAsStream("/"
+                    + name + ".properties");
+            props.load(in);
+            Iterator<Object> it = props.keySet().iterator();
+            Map<String, String> map = new HashMap<>();
+            while (it.hasNext()) {
+                String key = it.next().toString();
+                String value = props.getProperty(key);
+                map.put(key, value);
+            }
+            props.clone();
+            in.close();
+            return map;
+        } catch (Exception e) {
+            log.error("PropertiesUtil getMap Error", e);
+        }
+        return null;
+    }
+}

+ 31 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/ResultMapUtils.java

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

+ 124 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/StatusCode.java

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

+ 111 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/StringUtils.java

@@ -0,0 +1,111 @@
+package org.jeecg.modules.bytedance.common.utils;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author jeecg-boot
+ * 2019年12月5日19:57:58
+ */
+public class StringUtils {
+    private static final Pattern LINE_PATTERN = Pattern.compile("_(\\w)");
+    private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
+    public static final String COMMA = ",";
+
+    public static ArrayList<String> stringCutFromBrace(String origin) {
+        String pattern = "(?<=\\{)(.+?)(?=\\})";
+        Pattern p = Pattern.compile(pattern);
+        ArrayList<String> list = new ArrayList<>();
+        Matcher m = p.matcher(origin);
+        while (m.find()) {
+            list.add(m.group());
+        }
+        return list;
+    }
+    /**
+     * 将下划线风格转换为驼峰风格
+     * @param inputString
+     * @return
+     */
+    public static String underlineToCamehunp(String inputString){
+        StringBuilder sb = new StringBuilder();
+        boolean nextUppercase = false;
+        for (int i = 0; i < inputString.length(); i++) {
+            char c = inputString.charAt(i);
+            if (c == '_') {
+                if (sb.length()>0) {
+                    nextUppercase = true;
+                }
+            }else {
+                if (nextUppercase) {
+                    sb.append(Character.toUpperCase(c));
+                    nextUppercase = false;
+                }else {
+                    sb.append(Character.toLowerCase(c));
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    /** 下划线转驼峰 */
+    public static String lineToHump(String str) {
+        str = str.toLowerCase();
+        Matcher matcher = LINE_PATTERN.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    /** 驼峰转下划线(简单写法,效率低于{@link #humpToLine2(String)}) */
+    public static String humpToLine(String str) {
+        return str.replaceAll("[A-Z]", "_$0").toLowerCase();
+    }
+
+    /** 驼峰转下划线,效率比上面高 */
+    public static String humpToLine2(String str) {
+        Matcher matcher = HUMP_PATTERN.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    //中文转Unicode
+    public static String cnToUnicode(String cn) {
+        char[] chars = cn.toCharArray();
+        String returnStr = "";
+        for (int i = 0; i < chars.length; i++) {
+            returnStr += "\\u" + Integer.toString(chars[i], 16);
+        }
+        return returnStr;
+    }
+
+    //Unicode转中文方法
+    public static String unicodeToCn(String unicode) {
+        /** 以 \ u 分割,因为java注释也能识别unicode,因此中间加了一个空格*/
+        String[] strs = unicode.split("\\\\u");
+        String returnStr = "";
+        // 由于unicode字符串以 \ u 开头,因此分割出的第一个字符是""。
+        for (int i = 1; i < strs.length; i++) {
+            returnStr += (char) Integer.valueOf(strs[i], 16).intValue();
+        }
+        return returnStr;
+    }
+
+    public static String replaceBlank(String str) {
+        String dest = "";
+        if (str!=null) {
+            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+            Matcher m = p.matcher(str);
+            dest = m.replaceAll("");
+        }
+        return dest;
+    }
+}

+ 2 - 4
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java

@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.CacheConstant;
 import org.jeecg.common.constant.CommonConstant;
@@ -31,7 +30,6 @@ import org.jeecgframework.poi.excel.ExcelImportUtil;
 import org.jeecgframework.poi.excel.def.NormalExcelConstants;
 import org.jeecgframework.poi.excel.entity.ExportParams;
 import org.jeecgframework.poi.excel.entity.ImportParams;
-import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
 import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -186,7 +184,7 @@ public class SysDictController {
 		Result<String> result = new Result<String>();
 		String text = null;
 		try {
-			text = sysDictService.queryDictTextByKey(dictCode, key);
+			text = sysDictService.queryDictTextByKey(dictCode, key,null,null);
 			 result.setSuccess(true);
 			 result.setResult(text);
 		} catch (Exception e) {
@@ -250,7 +248,7 @@ public class SysDictController {
 					result.error500("字典Code格式不正确!");
 					return result;
 				}
-				List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys);
+				List<String> texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys,null,null);
 
 				result.setSuccess(true);
 				result.setResult(texts);

+ 6 - 8
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java

@@ -1,12 +1,9 @@
 package org.jeecg.modules.system.mapper;
 
-import java.util.List;
-import java.util.Map;
-
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Param;
-import org.apache.ibatis.annotations.ResultType;
 import org.apache.ibatis.annotations.Select;
 import org.apache.ibatis.annotations.Update;
 import org.jeecg.common.system.vo.DictModel;
@@ -15,7 +12,8 @@ import org.jeecg.modules.system.entity.SysDict;
 import org.jeecg.modules.system.model.DuplicateCheckVo;
 import org.jeecg.modules.system.model.TreeSelectModel;
 
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -46,13 +44,13 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
 	@Select("select ${key} as \"label\",${value} as \"value\" from ${table}")
 	public List<Map<String,String>> getDictByTableNgAlain(@Param("table") String table, @Param("key") String key, @Param("value") String value);
 
-	public String queryDictTextByKey(@Param("code") String code,@Param("key") String key);
+	public String queryDictTextByKey(@Param("code") String code,@Param("key") String key,@Param("extendsKey")String extendsKey,@Param("extendsValue")String extendsValue);
 
 	@Deprecated
-	public String queryTableDictTextByKey(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("key") String key);
+	public String queryTableDictTextByKey(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("key") String key,@Param("extendsKey")String extendsKey,@Param("extendsValue")String extendsValue);
 
 	@Deprecated
-	public List<DictModel> queryTableDictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray);
+	public List<DictModel> queryTableDictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray,@Param("extendsKey")String extendsKey,@Param("extendsValue")String extendsValue);
 
 	/**
 	 * 查询所有部门 作为字典信息 id -->value,departName -->text

+ 9 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml

@@ -14,6 +14,9 @@
 		   select s.item_text from sys_dict_item s 
 		   where s.dict_id = (select id from sys_dict where dict_code = #{code})
 		   and s.item_value = #{key}
+		<if test="extendsKey!=null and extendsValue!=null">
+			and s.${extendsKey} = #{extendsValue}
+		</if>
 	</select>
 
 
@@ -33,6 +36,9 @@
 	<!--通过查询指定table的 text code key 获取字典值-->
 	<select id="queryTableDictTextByKey" parameterType="String" resultType="String">
 		   select ${text} as "text" from ${table} where ${code}= #{key}
+		<if test="extendsKey!=null and extendsValue!=null">
+			and ${extendsKey} = #{extendsValue}
+		</if>
 	</select>
 
 	<!--通过查询指定table的 text code key 获取字典值,包含value-->
@@ -41,6 +47,9 @@
 		<foreach item="key" collection="keyArray" open="(" separator="," close=")">
 			#{key}
 		</foreach>
+		<if test="extendsKey!=null and extendsValue!=null">
+			and ${extendsKey} = #{extendsValue}
+		</if>
 	</select>
 
 	<!-- 重复校验 sql语句 -->

+ 7 - 7
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java

@@ -1,15 +1,15 @@
 package org.jeecg.modules.system.service;
 
-import java.util.List;
-import java.util.Map;
-
+import com.baomidou.mybatisplus.extension.service.IService;
 import org.jeecg.common.system.vo.DictModel;
 import org.jeecg.common.system.vo.DictQuery;
 import org.jeecg.modules.system.entity.SysDict;
-import com.baomidou.mybatisplus.extension.service.IService;
 import org.jeecg.modules.system.entity.SysDictItem;
 import org.jeecg.modules.system.model.TreeSelectModel;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * <p>
  * 字典表 服务类
@@ -30,13 +30,13 @@ public interface ISysDictService extends IService<SysDict> {
     @Deprecated
 	public List<DictModel> queryTableDictItemsByCodeAndFilter(String table, String text, String code, String filterSql);
 
-    public String queryDictTextByKey(String code, String key);
+    public String queryDictTextByKey(String code, String key,String ekey,String evalue);
 
     @Deprecated
-	String queryTableDictTextByKey(String table, String text, String code, String key);
+	String queryTableDictTextByKey(String table, String text, String code, String key,String extendsKey,String extendsValue);
 
 	@Deprecated
-	List<String> queryTableDictByKeys(String table, String text, String code, String keys);
+	List<String> queryTableDictByKeys(String table, String text, String code, String keys,String extendsKey,String extendsValue);
 
     /**
      * 根据字典类型删除关联表中其对应的数据

+ 7 - 10
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java

@@ -1,7 +1,4 @@
 package org.jeecg.modules.system.service.impl;
-import	java.util.HashMap;
-import	java.util.ArrayList;
-
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -111,13 +108,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 	}
 
 	@Override
-	public String translateDictFromTable(String table, String text, String code, String key) {
-		return sysDictService.queryTableDictTextByKey(table, text, code, key);
+	public String translateDictFromTable(String table, String text, String code, String key,String extendsKey,String extendsValue) {
+		return sysDictService.queryTableDictTextByKey(table, text, code, key,extendsKey,extendsValue);
 	}
 
 	@Override
-	public String translateDict(String code, String key) {
-		return sysDictService.queryDictTextByKey(code, key);
+	public String translateDict(String code, String key,String extendsKey,String extendsValue) {
+		return sysDictService.queryDictTextByKey(code, key,extendsKey,extendsValue);
 	}
 
 	@Override
@@ -534,7 +531,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 
 	@Override
 	public List<String> queryTableDictByKeys(String table, String text, String code, String[] keyArray) {
-		return sysDictService.queryTableDictByKeys(table,text,code,Joiner.on(",").join(keyArray));
+		return sysDictService.queryTableDictByKeys(table,text,code,Joiner.on(",").join(keyArray),null,null);
 	}
 
 	@Override
@@ -848,7 +845,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 
 	/**
 	 * 36根据多个用户账号(逗号分隔),查询返回多个用户信息
-	 * @param orgCodes
+	 * @param usernames
 	 * @return
 	 */
 	@Override
@@ -867,7 +864,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
 
 	/**
 	 * 37根据多个部门编码(逗号分隔),查询返回多个部门信息
-	 * @param usernames
+	 * @param orgCodes
 	 * @return
 	 */
 	@Override

+ 9 - 9
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java

@@ -16,11 +16,11 @@ import org.jeecg.modules.system.mapper.SysDictItemMapper;
 import org.jeecg.modules.system.mapper.SysDictMapper;
 import org.jeecg.modules.system.model.TreeSelectModel;
 import org.jeecg.modules.system.service.ISysDictService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -39,9 +39,9 @@ import java.util.stream.Collectors;
 @Slf4j
 public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements ISysDictService {
 
-    @Autowired
+    @Resource
     private SysDictMapper sysDictMapper;
-    @Autowired
+    @Resource
     private SysDictItemMapper sysDictItemMapper;
 
 	/**
@@ -87,9 +87,9 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 
 	@Override
 	@Cacheable(value = CacheConstant.SYS_DICT_CACHE,key = "#code+':'+#key")
-	public String queryDictTextByKey(String code, String key) {
+	public String queryDictTextByKey(String code, String key,String ekey,String evalue) {
 		log.debug("无缓存dictText的时候调用这里!");
-		return sysDictMapper.queryDictTextByKey(code, key);
+		return sysDictMapper.queryDictTextByKey(code, key,ekey,evalue);
 	}
 
 	/**
@@ -124,9 +124,9 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 	 */
 	@Override
 	@Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE)
-	public String queryTableDictTextByKey(String table,String text,String code, String key) {
+	public String queryTableDictTextByKey(String table,String text,String code, String key,String extendsKey,String extendsValue) {
 		log.debug("无缓存dictTable的时候调用这里!");
-		return sysDictMapper.queryTableDictTextByKey(table,text,code,key);
+		return sysDictMapper.queryTableDictTextByKey(table,text,code,key,extendsKey,extendsValue);
 	}
 
 	/**
@@ -142,12 +142,12 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
 	//update-begin--Author:lvdandan  Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
 	//@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE)
 	//update-end--Author:lvdandan  Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存
-	public List<String> queryTableDictByKeys(String table, String text, String code, String keys) {
+	public List<String> queryTableDictByKeys(String table, String text, String code, String keys,String extendsKey,String extendsValue) {
 		if(oConvertUtils.isEmpty(keys)){
 			return null;
 		}
 		String[] keyArray = keys.split(",");
-		List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray);
+		List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray,extendsKey,extendsValue);
 		List<String> texts = new ArrayList<>(dicts.size());
 		// 查询出来的顺序可能是乱的,需要排个序
 		for (String key : keyArray) {