Browse Source

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	module-toutiao/src/main/java/cn/com/ctop/toutiao/test/Test.java
xuzuoyun 5 years ago
parent
commit
8d55b4b3c0
36 changed files with 1376 additions and 353 deletions
  1. 1 1
      .gitignore
  2. 16 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/ResultMapUtils.java
  3. 85 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/StatusCode.java
  4. 9 23
      jeecg-boot-module-system/src/main/java/org/jeecg/JeecgOneToMainUtil.java
  5. 1 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
  6. 7 7
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ByteDanceAdvertiserPostController.java
  7. 74 10
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ByteDanceTemplateController.java
  8. 28 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TestController.java
  9. 7 6
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceAdvertisePlan.java
  10. 1 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceCampaign.java
  11. 1 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceCampaignTemplate.java
  12. 4 4
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceImageInfo.java
  13. 3 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceVideoInfo.java
  14. 6 5
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/UserAllocation.java
  15. 2 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceAdvertisePlanService.java
  16. 0 4
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceAdvertiserDataService.java
  17. 7 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceCampaignTemplateService.java
  18. 3 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceCreativeService.java
  19. 3 1
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IBytedanceAdvertisePlanTemplateService.java
  20. 9 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/ICreateInternalService.java
  21. 10 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IFileInfoService.java
  22. 4 6
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceAdvertisePlanServiceImpl.java
  23. 2 114
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceAdvertiserDataServiceImpl.java
  24. 1 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceBudgetTemplateServiceImpl.java
  25. 185 5
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceCampaignTemplateServiceImpl.java
  26. 189 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceCreativeServiceImpl.java
  27. 1 3
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceUserOrientationTemplateServiceImpl.java
  28. 85 27
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/BytedanceAdvertisePlanTemplateServiceImpl.java
  29. 1 5
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/BytedanceDeliveryTargetTemplateServiceImpl.java
  30. 399 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/CreateInternalServiceImpl.java
  31. 139 69
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/FileInfoServiceImpl.java
  32. 2 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java
  33. 13 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java
  34. 37 0
      module-common/src/main/java/cn/com/ctop/common/utils/HttpUtils.java
  35. 3 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/common/BytedanceInterfaceConstant.java
  36. 38 48
      module-toutiao/src/main/java/cn/com/ctop/toutiao/test/Test.java

+ 1 - 1
.gitignore

@@ -32,4 +32,4 @@ gen
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 hs_err_pid*
 **/target/
-application-dev.yml
+#application-dev.yml

+ 16 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/ResultMapUtils.java

@@ -0,0 +1,16 @@
+package org.jeecg.common.util;
+
+import java.util.Map;
+
+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));
+    }
+
+}

+ 85 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/StatusCode.java

@@ -0,0 +1,85 @@
+package org.jeecg.common.util;
+
+public enum StatusCode {
+    /**
+     * 0   请求成功
+     * -101 参数异常
+     * -102 服务器异常
+     * -103 数据不存在
+     * -104 渠道不存在
+     * -105 规则尚未配置
+     * -106 规则为空
+     * -107 同盾数据为空
+     * -108 模型服务异常
+     * -109 深度搜索服务异常
+     * -201 探针数据为空
+     */
+    COMMON_SUCCESS("success", 0, true),
+    COMMON_PARAM_ERROR("参数异常", -1, false),
+    BYTEDANCE_VIDEO_UPLOAD_FAIL("今日头条视频文件上传失败", -201, false),
+    IMAGE_NUMBER_SHORTAGE("今日头条图片文件上传失败", -202, false),
+    BYTEDANCE_IMAGE_UPLOAD_FAIL("今日头条图片文件上传失败", -203, false),
+    COMMON_SERVER_ERROR("server error", -102, false),
+    COMMON_DATA_HAS_EXIST_ERROR("data has exist", -103, false),
+    COMMON_CHANNEL_NOT_EXIST_ERROR("channel not exist", -104, false),
+    COMMON_RULEENGINE_HAS_NOT_CONFIGURED_ERROR("ruleEngine has not configured", -105, false),
+    COMMON_RULE_PACKAGE_IS_NULL_ERROR("rulepackage is null", -106, false),
+    COMMON_TONGDUN_DATA_IS_NULL_ERROR("tongdun data is null", -107, false),
+    COMMON_MODEL_SERVICE_ERROR("model service error", -108, false),
+    COMMON_DEEPSEARCH_ERROR("deep search error", -109, false),
+    COMMON_APPLICATION_MOBILE_IS_NULL_ERROR("application mobile is null", -110, false),
+    COMMON_TANZHEN_DATA_IS_NULL_ERROR("tanzhen data is null", -201, false),
+    COMMON_RULE_ERROR_APPLICATION_IS_NULL("there is no error application", -202, 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;
+    }
+
+}

+ 9 - 23
jeecg-boot-module-system/src/main/java/org/jeecg/JeecgOneToMainUtil.java

@@ -22,41 +22,27 @@ public class JeecgOneToMainUtil {
 	public static void main(String[] args) {
 		//第一步:设置主表配置
 		MainTableVo mainTable = new MainTableVo();
-		mainTable.setTableName("jeecg_order_main");//表名
-		mainTable.setEntityName("TestOrderMain");	 //实体名
-		mainTable.setEntityPackage("test2");	 //包名
-		mainTable.setFtlDescription("订单");	 //描述
+        mainTable.setTableName("sys_category");//表名
+        mainTable.setEntityName("Category");     //实体名
+        mainTable.setEntityPackage("ctop");     //包名
+        mainTable.setFtlDescription("主分类信息");     //描述
 		
 		//第二步:设置子表集合配置
 		List<SubTableVo> subTables = new ArrayList<SubTableVo>();
 		//[1].子表一
 		SubTableVo po = new SubTableVo();
-		po.setTableName("jeecg_order_customer");//表名
-		po.setEntityName("TestOrderCustom");	    //实体名
-		po.setEntityPackage("test2");	        //包名
-		po.setFtlDescription("客户明细");       //描述
+        po.setTableName("sys_category");//表名
+        po.setEntityName("ChildCategory");        //实体名
+        po.setEntityPackage("ctop");            //包名
+        po.setFtlDescription("子分类信息");       //描述
 		//子表外键参数配置
 		/*说明: 
 		 * a) 子表引用主表主键ID作为外键,外键字段必须以_ID结尾;
 		 * b) 主表和子表的外键字段名字,必须相同(除主键ID外);
 		 * c) 多个外键字段,采用逗号分隔;
 		*/
-		po.setForeignKeys(new String[]{"order_id"});
+        po.setForeignKeys(new String[]{"pid"});
 		subTables.add(po);
-		//[2].子表二
-		SubTableVo po2 = new SubTableVo();
-		po2.setTableName("jeecg_order_ticket");		//表名
-		po2.setEntityName("TestOrderTicket");			//实体名
-		po2.setEntityPackage("test2"); 				//包名
-		po2.setFtlDescription("产品明细");			//描述
-		//子表外键参数配置
-		/*说明: 
-		 * a) 子表引用主表主键ID作为外键,外键字段必须以_ID结尾;
-		 * b) 主表和子表的外键字段名字,必须相同(除主键ID外);
-		 * c) 多个外键字段,采用逗号分隔;
-		*/
-		po2.setForeignKeys(new String[]{"order_id"});
-		subTables.add(po2);
 		mainTable.setSubTables(subTables);
 		
 		//第三步:一对多(父子表)数据模型,代码生成

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

@@ -92,6 +92,7 @@ public class ShiroConfig {
 		filterChainDefinitionMap.put("/toutiao/dictitem/list", "anon");
 		filterChainDefinitionMap.put("/toutiao/advertiser/**", "anon");
         filterChainDefinitionMap.put("/toutiao/industry/list", "anon");
+        filterChainDefinitionMap.put("/template/bytedance/industry/list", "anon");
 		//文件上传接口
 		filterChainDefinitionMap.put("/upload/**", "anon");
 

+ 7 - 7
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ByteDanceAdvertiserPostController.java

@@ -175,7 +175,7 @@ public class ByteDanceAdvertiserPostController {
         data.put("download_type", "DOWNLOAD_URL");//坑
         data.put("package", "com.igg.android.lordsmobile_cn");//坑
         data.put("app_type", "APP_ANDROID");//坑
-        return advertisePlanService.advertiserPlanCreate(accountId, campaignId, data.toJSONString());
+        return advertisePlanService.advertiserPlanCreate(new CTopOauthToken(), campaignId, data.toJSONString());
     }
 
     /**
@@ -254,8 +254,8 @@ public class ByteDanceAdvertiserPostController {
      * @
      */
     @RequestMapping("/advertiser/video/add")
-    public Map<String, Object> advertiserVideoAdd(String accountId, Long videoFileId) {
-        return fileInfoService.uploadVideoToTemplate(accountId, videoFileId, "bytedance");
+    public Map<String, Object> advertiserVideoAdd(String accountId, String videoUrl) {
+        return fileInfoService.uploadVideoToBytedance(accountId, videoUrl);
     }
 
     /**
@@ -265,13 +265,13 @@ public class ByteDanceAdvertiserPostController {
      * @
      */
     @RequestMapping("/advertiser/image/add")
-    public Map<String, Object> advertiserImageAdd(String accountId, Long imageFileId) {
-        return fileInfoService.uploadImageToTemplate(accountId, imageFileId, "bytedance");
+    public Map<String, Object> advertiserImageAdd(String accountId, String imageUrl) {
+        return fileInfoService.uploadImageToBytedance(accountId, imageUrl);
     }
 
     @RequestMapping("/industry/list")
-    public Map<String, Object> industryList(String accountId) {
-        return fileInfoService.getIndustryList(accountId);
+    public Map<String, Object> industryList(String accountId, Integer level) {
+        return fileInfoService.getIndustryList(accountId, level);
     }
 
     @Autowired

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

@@ -1,13 +1,12 @@
 package org.jeecg.modules.ctop.controller;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.subject.Subject;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.system.query.QueryGenerator;
-import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.modules.ctop.entity.*;
 import org.jeecg.modules.ctop.service.*;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,6 +45,21 @@ public class ByteDanceTemplateController {
     }
 
     /**
+     * 广告组模板
+     * 完成
+     *
+     * @param template
+     * @return
+     */
+    @PostMapping("creative/insert")
+    public Map<String, Object> creativeInsert(@RequestBody JSONObject template) {
+        return creativeService.insertBatch(template);
+    }
+
+    @Autowired
+    private IByteDanceCreativeService creativeService;
+
+    /**
      * 投放目标
      *
      * @param template
@@ -57,6 +71,23 @@ public class ByteDanceTemplateController {
         return deliveryTargetTemplateService.insertTemplate(template);
     }
 
+    @PostMapping(value = "allocation/list")
+    public Result<IPage<UserAllocation>> queryPageList(@RequestBody UserAllocation userAllocation,
+                                                       @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                       @RequestParam(name = "pageSize", defaultValue = "100") Integer pageSize,
+                                                       HttpServletRequest req) {
+        Result<IPage<UserAllocation>> result = new Result<>();
+        QueryWrapper<UserAllocation> queryWrapper = QueryGenerator.initQueryWrapper(userAllocation, req.getParameterMap());
+        Page<UserAllocation> page = new Page<>(pageNo, pageSize);
+        IPage<UserAllocation> pageList = userAllocationService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    @Autowired
+    private IUserAllocationService userAllocationService;
+
     /**
      * 用户定向
      *
@@ -77,8 +108,8 @@ public class ByteDanceTemplateController {
      * @return
      */
     @PostMapping("advertiserplan/insert")
-    public Map<String, Object> advertiserplanTemplateInsert(@RequestBody BytedanceAdvertisePlanTemplate template, HttpServletRequest req) {
-        return advertisePlanTemplateService.insertTemplate(template);
+    public Map<String, Object> advertiserplanTemplateInsert(@RequestBody BytedanceAdvertisePlanTemplate template, String accountId, HttpServletRequest req) {
+        return advertisePlanTemplateService.insertTemplate(template, accountId);
     }
 
     /**
@@ -123,13 +154,11 @@ public class ByteDanceTemplateController {
      * @功能:获取广告组列表信息
      */
     @PostMapping(value = "campaign/data/list")
-    public Result<IPage<ByteDanceCampaign>> audiencePageList(ByteDanceCampaign campaign, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
-                                                             @RequestParam(name = "pageSize", defaultValue = "100") Integer pageSize, HttpServletRequest req) {
+    public Result<IPage<ByteDanceCampaign>> campaignPageList(@RequestBody ByteDanceCampaign campaign, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                             @RequestParam(name = "pageSize", defaultValue = "1000") Integer pageSize, HttpServletRequest req) {
         Result<IPage<ByteDanceCampaign>> result = new Result<>();
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        campaign.setAdvertiserId(user.getId());
         QueryWrapper<ByteDanceCampaign> queryWrapper = QueryGenerator.initQueryWrapper(campaign, req.getParameterMap());
-        queryWrapper.eq("advertiser_id", campaign.getAdvertiserId()).orderByAsc("id");
+        queryWrapper.eq("toutiao_id", campaign.getToutiaoId()).orderByAsc("id");
         Page<ByteDanceCampaign> page = new Page<>(pageNo, pageSize);
         IPage<ByteDanceCampaign> pageList = campaignService.page(page, queryWrapper);
         result.setSuccess(true);
@@ -137,6 +166,41 @@ public class ByteDanceTemplateController {
         return result;
     }
 
+    /**
+     * @param req
+     * @return
+     * @功能:获取头条行业信息列表
+     */
+    @GetMapping(value = "/bytedance/industry/list")
+    public JSONArray campaignPageList(HttpServletRequest req) {
+        return fileInfoService.getByteDanceIndustryList(req);
+    }
+
+    @Autowired
+    private IFileInfoService fileInfoService;
+
+    /**
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     * @功能:获取广告计划列表信息
+     */
+    @PostMapping(value = "plan/data/list")
+    public Result<IPage<ByteDanceAdvertisePlan>> planPageList(@RequestBody ByteDanceAdvertisePlan plan, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+                                                              @RequestParam(name = "pageSize", defaultValue = "1000") Integer pageSize, HttpServletRequest req) {
+        Result<IPage<ByteDanceAdvertisePlan>> result = new Result<>();
+        QueryWrapper<ByteDanceAdvertisePlan> queryWrapper = QueryGenerator.initQueryWrapper(plan, req.getParameterMap());
+        queryWrapper.eq("toutiao_id", plan.getToutiaoId()).orderByDesc("id");
+        Page<ByteDanceAdvertisePlan> page = new Page<>(pageNo, pageSize);
+        IPage<ByteDanceAdvertisePlan> pageList = planService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    @Autowired
+    private IByteDanceAdvertisePlanService planService;
     @Autowired
     private IByteDanceCampaignService campaignService;
 

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

@@ -0,0 +1,28 @@
+package org.jeecg.modules.ctop.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.ctop.entity.BindAccountAuth;
+import org.jeecg.modules.ctop.service.ICreateInternalService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/test")
+public class TestController {
+    @Autowired
+    private ICreateInternalService createInternalService;
+
+    @PostMapping(value = "/create")
+    public void authorization(@RequestBody JSONObject json) {
+        System.err.println(json);
+        createInternalService.createInternal(json);
+
+
+    }
+
+}

+ 7 - 6
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceAdvertisePlan.java

@@ -424,17 +424,17 @@ public class ByteDanceAdvertisePlan {
         }
     }
 
-    public ByteDanceAdvertisePlan(JSONObject dataObject, String accountId, Long adId, JSONObject params) {
+    public ByteDanceAdvertisePlan(String advertiserId, Long adId, JSONObject params) {
         this.id = adId;
-        this.advertiserId = accountId;
+        this.advertiserId = advertiserId;
         String name = params.getString("name");
         if (null != name && !"".equals(name.trim())) {
             this.name = name;
         }
 
-        Long advertiserId = params.getLong("advertiser_id");
-        if (null != advertiserId) {
-            this.toutiaoId = advertiserId;
+        Long toutiaoId = params.getLong("advertiser_id");
+        if (null != toutiaoId) {
+            this.toutiaoId = toutiaoId;
         }
         Long campaignId = params.getLong("campaign_id");
         if (null != campaignId) {
@@ -687,5 +687,6 @@ public class ByteDanceAdvertisePlan {
         }
     }
 
-
+    public ByteDanceAdvertisePlan() {
+    }
 }

+ 1 - 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceCampaign.java

@@ -175,7 +175,7 @@ public class ByteDanceCampaign {
 		this.name = template.getCampaignName();
 		this.budgetMode = template.getCampaignBudget();
 		this.budget = new BigDecimal(template.getBudgetDaily());
-		this.landingType = template.getPromotionPurpuse();
+        this.landingType = template.getPromotionPurpose();
 		this.toutiaoId = token.getAccountId();
 		this.templateId = template.getId();
 	}

+ 1 - 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceCampaignTemplate.java

@@ -42,7 +42,7 @@ public class ByteDanceCampaignTemplate {
     @Excel(name = "投放目标", width = 15)
     @ApiModelProperty(value = "投放目标")
     @Dict(dicCode = "toutiao_promotion_purpose_type")
-    private String promotionPurpuse;
+    private String promotionPurpose;
     /**
      * 投放方式
      */

+ 4 - 4
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceImageInfo.java

@@ -41,7 +41,7 @@ public class ByteDanceImageInfo {
      */
     @Excel(name = "文件id", width = 15)
     @ApiModelProperty(value = "文件id")
-    private Long fileId;
+    private String fileId;
     /**
      * 头条平台账号id
      */
@@ -105,9 +105,9 @@ public class ByteDanceImageInfo {
     @ApiModelProperty(value = "updateTime")
     private Date updateTime;
 
-    public ByteDanceImageInfo(JSONObject data, CTopOauthToken token, Long imageFileId) {
-        this.id = data.getString("video_id");
-        this.fileId = imageFileId;
+    public ByteDanceImageInfo(JSONObject data, CTopOauthToken token) {
+        this.id = data.getString("id");
+        this.fileId = id;
         this.accountId = token.getAccountId();
         this.advertiserId = token.getAdvertiserId();
         this.width = data.getInteger("width");

+ 3 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/ByteDanceVideoInfo.java

@@ -41,7 +41,7 @@ public class ByteDanceVideoInfo {
      */
     @Excel(name = "对应本文件id", width = 15)
     @ApiModelProperty(value = "对应本文件id")
-    private Long fileId;
+    private String fileId;
     /**
      * 平台账号id
      */
@@ -101,9 +101,9 @@ public class ByteDanceVideoInfo {
     @ApiModelProperty(value = "updateTime")
     private Date updateTime;
 
-    public ByteDanceVideoInfo(JSONObject data, CTopOauthToken token, Long fileId) {
+    public ByteDanceVideoInfo(JSONObject data, CTopOauthToken token) {
         this.id = data.getString("video_id");
-        this.fileId = fileId;
+        this.fileId = id;
         this.accountId = token.getAccountId();
         this.advertiserId = token.getAdvertiserId();
         this.width = data.getInteger("width");

+ 6 - 5
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/entity/UserAllocation.java

@@ -1,23 +1,24 @@
 package org.jeecg.modules.ctop.entity;
 
+import java.io.Serializable;
+import java.util.Date;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableField;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
-import org.jeecgframework.poi.excel.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import org.springframework.format.annotation.DateTimeFormat;
-
-import java.util.Date;
+import org.jeecgframework.poi.excel.annotation.Excel;
 
 /**
  * @Description: 用户分配
  * @Author: jeecg-boot
- * @Date: 2019-07-31
+ * @Date:   2019-07-30
  * @Version: V1.0
  */
 @Data

+ 2 - 1
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceAdvertisePlanService.java

@@ -2,6 +2,7 @@ package org.jeecg.modules.ctop.service;
 
 import org.jeecg.modules.ctop.entity.ByteDanceAdvertisePlan;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.ctop.entity.CTopOauthToken;
 
 import java.util.Map;
 
@@ -13,5 +14,5 @@ import java.util.Map;
  */
 public interface IByteDanceAdvertisePlanService extends IService<ByteDanceAdvertisePlan> {
 
-    Map<String, Object> advertiserPlanCreate(String accountId, Long campaignId, String dataString);
+    Map<String, Object> advertiserPlanCreate(CTopOauthToken token, Long campaignId, String dataString);
 }

+ 0 - 4
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceAdvertiserDataService.java

@@ -18,8 +18,6 @@ public interface IByteDanceAdvertiserDataService {
 
     Map<String, Object> getAdvertiserCreativeMaterial(String accountId, String creativeIds);
 
-    Map<String, Object> advertiserCampaignCreate(String accountId, String campaignName, String budgetMode, Integer budget, String landingType);
-
     Map<String, Object> advertiserCampaignUpdateStatus(String accountId, String campaignIds, String optStatus);
 
     Map<String, Object> advertiserCampaignUpdate(String accountId, Long campaignId, String budgetMode, Integer budget,String campaignName);
@@ -33,6 +31,4 @@ public interface IByteDanceAdvertiserDataService {
     Map<String, Object> advertiserCreativeUpdateStatus(String accountId, String ids, String optStatus);
 
     Map<String, Object> advertiserCustomAudienceSelect(String accountId);
-
-    Map<String, Object> campaignCreate(CTopOauthToken token, ByteDanceCampaignTemplate template);
 }

+ 7 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IByteDanceCampaignTemplateService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.ctop.entity.ByteDanceCampaignTemplate;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.ctop.entity.CTopOauthToken;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.Map;
@@ -19,4 +20,10 @@ public interface IByteDanceCampaignTemplateService extends IService<ByteDanceCam
     Map<String, Object> insertTemplate(ByteDanceCampaignTemplate template);
 
     Result<IPage<ByteDanceCampaignTemplate>> getList(ByteDanceCampaignTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req);
+
+    Map<String, Object> campaignCreate(CTopOauthToken token, ByteDanceCampaignTemplate template);
+
+    Map<String, Object> campaignCreate(String getAccountId, Long campaignId, String getName);
+
+    Map<String, Object> campaignCreate(String accountId, String campaignName, String budgetMode, Integer budget, String landingType);
 }

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

@@ -1,5 +1,6 @@
 package org.jeecg.modules.ctop.service;
 
+import com.alibaba.fastjson.JSONObject;
 import org.jeecg.modules.ctop.entity.ByteDanceCreative;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -14,4 +15,6 @@ import java.util.Map;
 public interface IByteDanceCreativeService extends IService<ByteDanceCreative> {
 
     Map<String, Object> creativeCreate(String accountId, Long campaignId, String dataString);
+
+    Map<String, Object> insertBatch(JSONObject template);
 }

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

@@ -13,5 +13,7 @@ import java.util.Map;
  */
 public interface IBytedanceAdvertisePlanTemplateService extends IService<BytedanceAdvertisePlanTemplate> {
 
-    Map<String, Object> insertTemplate(BytedanceAdvertisePlanTemplate template);
+    Map<String, Object> insertTemplate(BytedanceAdvertisePlanTemplate template, String accountId);
+
+    Map<String, Object> planCreate(Long campaignId, String getAccountId, String deliveryRange, Long userorentationId, Long budgetId, Long deliverytargetId, String getName);
 }

+ 9 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/ICreateInternalService.java

@@ -0,0 +1,9 @@
+package org.jeecg.modules.ctop.service;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.Map;
+
+public interface ICreateInternalService {
+    Map<String, Object> createInternal(JSONObject requestJson);
+}

+ 10 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/IFileInfoService.java

@@ -1,8 +1,11 @@
 package org.jeecg.modules.ctop.service;
 
+import com.alibaba.fastjson.JSONArray;
+import io.swagger.models.auth.In;
 import org.jeecg.modules.ctop.entity.FileInfo;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.Map;
 
 /**
@@ -13,9 +16,13 @@ import java.util.Map;
  */
 public interface IFileInfoService extends IService<FileInfo> {
 
-    Map<String, Object> uploadVideoToTemplate(String accountId, Long videoFileId, String templatename);
+    Map<String, Object> uploadVideoToBytedance(String accountId, String videoUrl);
 
-    Map<String, Object> uploadImageToTemplate(String accountId, Long imageFileId, String templatename);
+    Map<String, Object> upload3ImagesToBytedance(String accountId, String imageFileUrls);
 
-    Map<String, Object> getIndustryList(String accountId);
+    Map<String, Object> uploadImageToBytedance(String accountId, String imageFileId);
+
+    Map<String, Object> getIndustryList(String accountId, Integer level);
+
+    JSONArray getByteDanceIndustryList(HttpServletRequest req);
 }

+ 4 - 6
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceAdvertisePlanServiceImpl.java

@@ -39,10 +39,8 @@ public class ByteDanceAdvertisePlanServiceImpl extends ServiceImpl<ByteDanceAdve
     private static final Logger logger = LoggerFactory.getLogger(ByteDanceAdvertisePlanServiceImpl.class);
 
     @Override
-    public Map<String, Object> advertiserPlanCreate(String accountId, Long campaignId, String dataString) {
+    public Map<String, Object> advertiserPlanCreate(CTopOauthToken token, Long campaignId, String dataString) {
         Map<String, Object> resultMap = new HashMap<>();
-        //1:获取token
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(accountId);
         JSONObject data = JSONObject.parseObject(dataString);
         data.put("advertiser_id", token.getAccountId());
         data.put("campaign_id", campaignId);
@@ -50,14 +48,14 @@ public class ByteDanceAdvertisePlanServiceImpl extends ServiceImpl<ByteDanceAdve
         Integer code = result.getInteger("code");
         String message = result.getString("message");
         if (null == code || code != 0) {
-            logger.info("广告计划创建失败,accountId:{},message:{}", accountId, message);
+            logger.info("广告计划创建失败,广告主id:{},message:{}", token.getAdvertiserId(), message);
             resultMap.put("code", -1);
-            resultMap.put("message", "广告计划创建失败");
+            resultMap.put("message", message);
             return resultMap;
         }
         JSONObject dataObject = result.getJSONObject("data");
         Long adId = dataObject.getLong("ad_id");
-        ByteDanceAdvertisePlan plan = new ByteDanceAdvertisePlan(dataObject, accountId, adId, data);
+        ByteDanceAdvertisePlan plan = new ByteDanceAdvertisePlan(token.getAdvertiserId(), adId, data);
         planMapper.insert(plan);
         resultMap.put("code", 0);
         resultMap.put("message", "广告计划创建成功");

+ 2 - 114
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceAdvertiserDataServiceImpl.java

@@ -244,87 +244,6 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
     }
 
     @Override
-    public Map<String, Object> advertiserCampaignCreate(String accountId, String campaignName, String budgetMode, Integer budget, String landingType) {
-        Map<String, Object> resultMap = new HashMap<>();
-        CTopOauthToken token = getOAuthTokenByAccountId(accountId);
-        //2: 根据token以及用户id获取用户信息数据
-        JSONObject params = new JSONObject();
-        params.put("advertiser_id", token.getAccountId());
-        params.put("campaign_name", campaignName);
-        params.put("budget_mode", budgetMode);
-        params.put("budget", budget);
-        params.put("landing_type", landingType);
-        JSONObject result = createCampaign(params, token.getAccessToken());
-        Integer code = result.getInteger("code");
-
-        if (null == code || !code.equals(0)) {
-            logger.info("创建广告组接口异常==》accountId:{},message:{}", accountId, result.getString("message"));
-            resultMap.put("code", -1);
-            resultMap.put("message", "创建广告组接口异常");
-            return resultMap;
-        }
-        JSONObject data = result.getJSONObject("data");
-        if (null == data) {
-            logger.info("广告组创建异常==》accountId:{},message:{}", accountId, result.getString("message"));
-            resultMap.put("code", -1);
-            resultMap.put("message", "广告组创建异常");
-            return resultMap;
-        }
-        Long id = data.getLong("campaign_id");
-        ByteDanceCampaign campaign = new ByteDanceCampaign(id, token, campaignName, budgetMode, budget, landingType);
-        //清除清数据,插入新数据
-        campaignMapper.insert(campaign);
-        resultMap.put("code", 0);
-        resultMap.put("message", "广告组创建成功");
-        return resultMap;
-    }
-
-    public JSONObject createCampaign(JSONObject data, String token) {
-        // 请求地址
-        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_create");
-
-        // 构造请求
-        HttpPost httpEntity = new HttpPost(url);
-
-        httpEntity.setHeader("Access-Token", token);
-
-        CloseableHttpResponse response = null;
-        CloseableHttpClient client = null;
-
-        try {
-            client = HttpClientBuilder.create().build();
-            httpEntity.setEntity(new StringEntity(data.toJSONString(), ContentType.APPLICATION_JSON));
-
-            response = client.execute(httpEntity);
-            if (response != null && response.getStatusLine().getStatusCode() == 200) {
-                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
-                StringBuffer result = new StringBuffer();
-                String line = "";
-                while ((line = bufferedReader.readLine()) != null) {
-                    result.append(line);
-                }
-                bufferedReader.close();
-                return JSONObject.parseObject(result.toString());
-            }
-
-        } catch (ClientProtocolException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            try {
-                if (response != null) {
-                    response.close();
-                }
-                client.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        return null;
-    }
-
-    @Override
     public Map<String, Object> advertiserCampaignUpdateStatus(String accountId, String campaignIds, String optStatus) {
         Map<String, Object> resultMap = new HashMap<>();
         JSONArray ids = new JSONArray();
@@ -692,40 +611,9 @@ public class ByteDanceAdvertiserDataServiceImpl implements IByteDanceAdvertiserD
         return resultMap;
     }
 
-    @Override
-    public Map<String, Object> campaignCreate(CTopOauthToken token, ByteDanceCampaignTemplate template) {
-        Map<String, Object> resultMap = new HashMap<>();
-        //2: 根据token以及用户id获取用户信息数据
-        JSONObject params = new JSONObject();
-        params.put("advertiser_id", token.getAccountId());
-        params.put("campaign_name", template.getCampaignName());
-        params.put("budget_mode", template.getCampaignBudget());
-        params.put("budget", template.getBudgetDaily());
-        params.put("landing_type", template.getPromotionPurpuse());
-        JSONObject result = createCampaign(params, token.getAccessToken());
-        Integer code = result.getInteger("code");
+    @Autowired
+    private ByteDanceCampaignTemplateMapper campaignTemplateMapper;
 
-        if (null == code || !code.equals(0)) {
-            logger.info("创建广告组接口异常==》accountId:{},message:{}", token.getAccountId(), result.getString("message"));
-            resultMap.put("code", -1);
-            resultMap.put("message", result.getString("message"));
-            return resultMap;
-        }
-        JSONObject data = result.getJSONObject("data");
-        if (null == data) {
-            logger.info("广告组创建异常==》accountId:{},message:{}", token.getAccountId(), result.getString("message"));
-            resultMap.put("code", -1);
-            resultMap.put("message", "广告组创建异常");
-            return resultMap;
-        }
-        Long id = data.getLong("campaign_id");
-        ByteDanceCampaign campaign = new ByteDanceCampaign(id, token, template);
-        //清除清数据,插入新数据
-        campaignMapper.insert(campaign);
-        resultMap.put("code", 0);
-        resultMap.put("message", "广告组创建成功");
-        return resultMap;
-    }
 
     @Autowired
     private ByteDanceCustomAudienceMapper audienceMapper;

+ 1 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceBudgetTemplateServiceImpl.java

@@ -62,11 +62,9 @@ public class ByteDanceBudgetTemplateServiceImpl extends ServiceImpl<ByteDanceBud
 
     @Override
     public Result<IPage<ByteDanceBudgetTemplate>> getList(ByteDanceBudgetTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req) {
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
         Result<IPage<ByteDanceBudgetTemplate>> result = new Result<>();
         QueryWrapper<ByteDanceBudgetTemplate> queryWrapper = QueryGenerator.initQueryWrapper(template, req.getParameterMap());
-        queryWrapper.eq("advertiser_id", token.getAdvertiserId()).orderByDesc("create_time");
+        queryWrapper.orderByDesc("create_time");
         Page<ByteDanceBudgetTemplate> page = new Page<>(pageNo, pageSize);
         IPage<ByteDanceBudgetTemplate> pageList = this.page(page, queryWrapper);
         result.setSuccess(true);

+ 185 - 5
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceCampaignTemplateServiceImpl.java

@@ -1,8 +1,17 @@
 package org.jeecg.modules.ctop.service.impl;
 
+import cn.com.ctop.common.utils.PropertiesUtils;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.system.query.QueryGenerator;
@@ -10,18 +19,27 @@ import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.modules.ctop.entity.ByteDanceCampaign;
 import org.jeecg.modules.ctop.entity.ByteDanceCampaignTemplate;
 import org.jeecg.modules.ctop.entity.CTopOauthToken;
+import org.jeecg.modules.ctop.mapper.ByteDanceCampaignMapper;
 import org.jeecg.modules.ctop.mapper.ByteDanceCampaignTemplateMapper;
 import org.jeecg.modules.ctop.service.IByteDanceAdvertiserDataService;
 import org.jeecg.modules.ctop.service.IByteDanceCampaignTemplateService;
 import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
 import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.logging.SimpleFormatter;
 
 /**
  * @Description: 今日头条广告组模板信息
@@ -31,25 +49,28 @@ import java.util.Map;
  */
 @Service
 public class ByteDanceCampaignTemplateServiceImpl extends ServiceImpl<ByteDanceCampaignTemplateMapper, ByteDanceCampaignTemplate> implements IByteDanceCampaignTemplateService {
-
+    private static final Logger logger = LoggerFactory.getLogger(ByteDanceCampaignTemplateServiceImpl.class);
     @Override
     public Map<String, Object> insertTemplate(ByteDanceCampaignTemplate template) {
         Map<String, Object> resultMap = new HashMap<>();
         LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
         CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
         campaignTemplateMapper.insert(template);
-        return advertiserDataService.campaignCreate(token, template);
+        //新增数据
+        //        return advertiserDataService.campaignCreate(token, template);
+        resultMap.put("success", true);
+        resultMap.put("message", "广告组模板创建成功");
+        resultMap.put("code", 0);
+        return resultMap;
     }
 
     @Autowired
     private IByteDanceAdvertiserDataService advertiserDataService;
     @Override
     public Result<IPage<ByteDanceCampaignTemplate>> getList(ByteDanceCampaignTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req) {
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
         Result<IPage<ByteDanceCampaignTemplate>> result = new Result<>();
         QueryWrapper<ByteDanceCampaignTemplate> queryWrapper = QueryGenerator.initQueryWrapper(template, req.getParameterMap());
-        queryWrapper.eq("advertiser_id", token.getAdvertiserId()).orderByDesc("create_time");
+        queryWrapper.orderByDesc("create_time");
         Page<ByteDanceCampaignTemplate> page = new Page<>(pageNo, pageSize);
         IPage<ByteDanceCampaignTemplate> pageList = this.page(page, queryWrapper);
         result.setSuccess(true);
@@ -57,8 +78,167 @@ public class ByteDanceCampaignTemplateServiceImpl extends ServiceImpl<ByteDanceC
         return result;
     }
 
+    @Override
+    public Map<String, Object> campaignCreate(String accountId, String campaignName, String budgetMode, Integer budget, String landingType) {
+        Map<String, Object> resultMap = new HashMap<>();
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(accountId);
+        //2: 根据token以及用户id获取用户信息数据
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("campaign_name", campaignName);
+        params.put("budget_mode", budgetMode);
+        params.put("budget", budget);
+        params.put("landing_type", landingType);
+        JSONObject result = createCampaign(params, token.getAccessToken());
+        Integer code = result.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            logger.info("创建广告组接口异常==》accountId:{},message:{}", accountId, result.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "创建广告组接口异常");
+            return resultMap;
+        }
+        JSONObject data = result.getJSONObject("data");
+        if (null == data) {
+            logger.info("广告组创建异常==》accountId:{},message:{}", accountId, result.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告组创建异常");
+            return resultMap;
+        }
+        Long id = data.getLong("campaign_id");
+        ByteDanceCampaign campaign = new ByteDanceCampaign(id, token, campaignName, budgetMode, budget, landingType);
+        //清除清数据,插入新数据
+        campaignMapper.insert(campaign);
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告组创建成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> campaignCreate(CTopOauthToken token, ByteDanceCampaignTemplate template) {
+        Map<String, Object> resultMap = new HashMap<>();
+        //2: 根据token以及用户id获取用户信息数据
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        params.put("campaign_name", template.getCampaignName());
+        params.put("budget_mode", template.getCampaignBudget());
+        params.put("budget", template.getBudgetDaily());
+        params.put("landing_type", template.getPromotionPurpose());
+        JSONObject result = createCampaign(params, token.getAccessToken());
+        Integer code = result.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            logger.info("创建广告组接口异常==》accountId:{},message:{}", token.getAccountId(), result.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", result.getString("message"));
+            return resultMap;
+        }
+        JSONObject data = result.getJSONObject("data");
+        if (null == data) {
+            logger.info("广告组创建异常==》accountId:{},message:{}", token.getAccountId(), result.getString("message"));
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告组创建异常");
+            return resultMap;
+        }
+        Long id = data.getLong("campaign_id");
+        ByteDanceCampaign campaign = new ByteDanceCampaign(id, token, template);
+        //清除清数据,插入新数据
+        campaignMapper.insert(campaign);
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告组创建成功");
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> campaignCreate(String getAccountId, Long campaignId, String name) {
+        ByteDanceCampaignTemplate template = campaignTemplateMapper.selectById(campaignId);
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(getAccountId);
+        Map<String, Object> resultMap = new HashMap<>();
+        //2: 根据token以及用户id获取用户信息数据
+        JSONObject params = new JSONObject();
+        params.put("advertiser_id", token.getAccountId());
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_hh_mm_ss");
+        params.put("campaign_name", name + sdf.format(name + "_广告组_" + new Date()) + "汇创思拓_" + System.currentTimeMillis());
+        params.put("budget_mode", template.getCampaignBudget());
+        params.put("budget", template.getBudgetDaily());
+        params.put("landing_type", template.getPromotionPurpose());
+        JSONObject result = createCampaign(params, token.getAccessToken());
+        Integer code = result.getInteger("code");
+
+        if (null == code || !code.equals(0)) {
+            logger.info("创建广告组接口异常==》accountId:{},message:{}", token.getAccountId(), result.getString("message"));
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", result.getString("message"));
+            return resultMap;
+        }
+        JSONObject data = result.getJSONObject("data");
+        if (null == data) {
+            logger.info("广告组创建异常==》accountId:{},message:{}", token.getAccountId(), result.getString("message"));
+            resultMap.put("success", false);
+            resultMap.put("code", -1);
+            resultMap.put("message", "广告组创建异常");
+            return resultMap;
+        }
+        Long id = data.getLong("campaign_id");
+        ByteDanceCampaign campaign = new ByteDanceCampaign(id, token, template);
+        //清除清数据,插入新数据
+        campaignMapper.insert(campaign);
+        resultMap.put("campaignId", id);
+        resultMap.put("success", true);
+        resultMap.put("code", 0);
+        resultMap.put("message", "广告组创建成功");
+        return resultMap;
+    }
+
+    public JSONObject createCampaign(JSONObject data, String token) {
+        // 请求地址
+        String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_create");
+        // 构造请求
+        HttpPost httpEntity = new HttpPost(url);
+
+        httpEntity.setHeader("Access-Token", token);
+
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
+
+        try {
+            client = HttpClientBuilder.create().build();
+            httpEntity.setEntity(new StringEntity(data.toJSONString(), ContentType.APPLICATION_JSON));
+
+            response = client.execute(httpEntity);
+            if (response != null && response.getStatusLine().getStatusCode() == 200) {
+                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
+                StringBuffer result = new StringBuffer();
+                String line = "";
+                while ((line = bufferedReader.readLine()) != null) {
+                    result.append(line);
+                }
+                bufferedReader.close();
+                return JSONObject.parseObject(result.toString());
+            }
+
+        } catch (ClientProtocolException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                client.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
     @Autowired
     private ByteDanceCampaignTemplateMapper campaignTemplateMapper;
     @Autowired
     private ICTopOauthTokenService tokenService;
+    @Autowired
+    private ByteDanceCampaignMapper campaignMapper;
 }

+ 189 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceCreativeServiceImpl.java

@@ -1,7 +1,9 @@
 package org.jeecg.modules.ctop.service.impl;
 
 import cn.com.ctop.common.utils.PropertiesUtils;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import io.swagger.models.auth.In;
 import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpPost;
@@ -12,8 +14,7 @@ import org.apache.http.impl.client.HttpClientBuilder;
 import org.jeecg.modules.ctop.entity.ByteDanceCreative;
 import org.jeecg.modules.ctop.entity.CTopOauthToken;
 import org.jeecg.modules.ctop.mapper.ByteDanceCreativeMapper;
-import org.jeecg.modules.ctop.service.IByteDanceCreativeService;
-import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
+import org.jeecg.modules.ctop.service.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -50,17 +51,202 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
         String message = result.getString("message");
         if (null == code || code != 0) {
             logger.info("广告创意创建失败,accountId:{},message:{}", accountId, message);
+            resultMap.put("success", false);
             resultMap.put("code", -1);
             resultMap.put("message", message);
             return resultMap;
         }
         JSONObject dataObject = result.getJSONObject("data");
-//        Long adId = dataObject.getLong("ad_id");
+        resultMap.put("success", true);
         resultMap.put("code", 0);
         resultMap.put("message", "广告创意创建成功");
         return resultMap;
     }
 
+    @Autowired
+    private IFileInfoService fileInfoService;
+    @Autowired
+    private IByteDanceCampaignTemplateService campaignTemplateService;
+    @Autowired
+    private IBytedanceAdvertisePlanTemplateService planTemplateService;
+
+    @Override
+    public Map<String, Object> insertBatch(JSONObject template) {
+        System.out.println(template.toJSONString());
+        String getName = template.getString("name");
+        String getAccountId = template.getLong("accountId") + "";
+        Long campaignTemplateId = template.getLong("campaignId");
+        String deliveryRange = template.getString("deliveryRange");
+        Long userorentationId = template.getLong("userorentationId");
+        Long budgetId = template.getLong("budgetId");
+        Long deliverytargetId = template.getLong("deliverytargetId");
+        //1:创建广告组
+        Map<String, Object> campaignResult = campaignTemplateService.campaignCreate(getAccountId, campaignTemplateId, getName);
+        Boolean createSuccess = (Boolean) campaignResult.get("success");
+        if (null == createSuccess || !createSuccess) {
+            return campaignResult;
+        }
+        Long campaignId = (Long) campaignResult.get("campaignId");
+        //2:创建广告计划
+        Map<String, Object> planResult = planTemplateService.planCreate(campaignId, getAccountId, deliveryRange, userorentationId, budgetId, deliverytargetId, getName);
+        createSuccess = (Boolean) planResult.get("success");
+        if (null == createSuccess || !createSuccess) {
+            return planResult;
+        }
+        Long planId = (Long) campaignResult.get("planId");
+        //3:创建广告创意
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_VIDEO">横版视频</a-radio-button>
+        JSONArray horizonImageIds = new JSONArray();
+        String horizonVideoId = "";
+        String horizonVideoCoverImageId = "";
+
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_VIDEO_VERTICAL">竖版视频</a-radio-button>
+        String verticalVideoId = "";
+        String verticalVideoCoverImageId = "";
+
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_GROUP">组图</a-radio-button>
+        JSONArray groupImageIds = new JSONArray();
+
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_SMALL">小图</a-radio-button>
+        JSONArray smallImageIds = new JSONArray();
+
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_LARGE_VERTICAL">大图竖图</a-radio-button>
+        JSONArray verticalImageIds = new JSONArray();
+
+//        creative_display_mode
+        JSONObject data = new JSONObject();
+        data.put("ad_id", planId);
+        String advertiseLoaction = template.getString("advertiseLocation");
+        //优选广告位
+        if (null != advertiseLoaction && "great".equals(advertiseLoaction)) {
+            data.put("smart_inventory", 1);
+        } else {
+            data.put("smart_inventory", 0);
+        }
+        //按媒体指定位置
+        if (null != advertiseLoaction && "media".equals(advertiseLoaction)) {
+            JSONArray inventoryType = template.getJSONArray("inventoryType");
+            data.put("inventory_type", inventoryType);
+        }
+        //按场景指定位置
+        if (null != advertiseLoaction && "sence".equals(advertiseLoaction)) {
+            data.put("scene_inventory", template.getString("sceneInventory"));
+        }
+        JSONArray creatives = new JSONArray();
+
+        //<a-radio-button value="">大图横图</a-radio-button>
+        String horizonImageUrl = template.getString("horizonImageUrl");
+        String horizonImageCreativeText = template.getString("horizonImageCreativeText");
+        if (null != horizonImageUrl && !"".equals(horizonImageUrl) && null != horizonImageCreativeText && !"".equals(horizonImageCreativeText)) {
+            JSONObject creative = new JSONObject();
+            creative.put("image_mode", "CREATIVE_IMAGE_MODE_LARGE");
+//            Map<String,Object> getImageResult = fileInfoService.uploadImageToBytedance(getAccountId,horizonImageUrl);
+//            JSONArray imageArray = (JSONArray) getImageResult.get("imageIds");
+//            web.business.image/201908015d0dd63849aa78f142989c70
+            JSONArray imageArray = new JSONArray();
+            imageArray.add("web.business.image/201908015d0dd63849aa78f142989c70");
+            creative.put("image_ids", imageArray);
+            creative.put("title", horizonImageCreativeText);
+            creatives.add(creative);
+        }
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_VIDEO">横版视频</a-radio-button>
+        String horizonVideoUrl = template.getString("horizonVideoUrl");
+        String horizonVideoCoverImageUrl = template.getString("horizonVideoCoverImageUrl");
+        String horizonVideoCreativeText = template.getString("horizonVideoCreativeText");
+        if (null != horizonVideoUrl && !"".equals(horizonVideoUrl) && null != horizonVideoCoverImageUrl && !"".equals(horizonVideoCoverImageUrl) && null != horizonVideoCreativeText && !"".equals(horizonVideoCreativeText)) {
+            JSONObject creative = new JSONObject();
+            creative.put("image_mode", "CREATIVE_IMAGE_MODE_VIDEO");
+            Map<String, Object> getImageResult = fileInfoService.uploadImageToBytedance(getAccountId, horizonVideoCoverImageUrl);
+            JSONArray imageArray = (JSONArray) getImageResult.get("imageIds");
+            Map<String, Object> getVideoResult = fileInfoService.uploadVideoToBytedance(getAccountId, horizonVideoCreativeText);
+            String videoId = (String) getVideoResult.get("videoId");
+            creative.put("image_id", imageArray.getString(0));
+            creative.put("video_id", videoId);
+            creative.put("title", horizonVideoCreativeText);
+            creatives.add(creative);
+        }
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_VIDEO_VERTICAL">竖版视频</a-radio-button>
+        String verticalVideoUrl = template.getString("verticalVideoUrl");
+        String verticalVideoCoverImageUrl = template.getString("verticalVideoCoverImageUrl");
+        String verticalVideoCreativeText = template.getString("verticalVideoCreativeText");
+        if (null != verticalVideoUrl && !"".equals(verticalVideoUrl) && null != verticalVideoCoverImageUrl && !"".equals(verticalVideoCoverImageUrl) && null != verticalVideoCreativeText && !"".equals(verticalVideoCreativeText)) {
+            JSONObject creative = new JSONObject();
+            creative.put("image_mode", "CREATIVE_IMAGE_MODE_VIDEO_VERTICAL");
+            Map<String, Object> getImageResult = fileInfoService.uploadImageToBytedance(getAccountId, verticalVideoCoverImageUrl);
+            JSONArray imageArray = (JSONArray) getImageResult.get("imageIds");
+            Map<String, Object> getVideoResult = fileInfoService.uploadVideoToBytedance(getAccountId, verticalVideoUrl);
+            String videoId = (String) getVideoResult.get("videoId");
+            creative.put("image_id", imageArray.getString(0));
+            creative.put("video_id", videoId);
+            creative.put("title", verticalVideoCreativeText);
+            creatives.add(creative);
+        }
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_GROUP">组图</a-radio-button>
+        String groupImageUrl = template.getString("groupImageUrl");
+        String groupImageCreativeText = template.getString("groupImageCreativeText");
+        if (null != groupImageUrl && !"".equals(groupImageUrl) && null != groupImageCreativeText && !"".equals(groupImageCreativeText)) {
+            JSONObject creative = new JSONObject();
+            creative.put("image_mode", "CREATIVE_IMAGE_MODE_GROUP");
+            Map<String, Object> getImageResult = fileInfoService.uploadImageToBytedance(getAccountId, groupImageUrl);
+            JSONArray imageArray = (JSONArray) getImageResult.get("imageIds");
+            creative.put("image_ids", imageArray);
+            creative.put("title", groupImageCreativeText);
+            creatives.add(creative);
+        }
+
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_SMALL">小图</a-radio-button>
+        String smallImageUrl = template.getString("smallImageUrl");
+        String smallImageCreativeText = template.getString("smallImageCreativeText");
+        if (null != smallImageUrl && !"".equals(smallImageUrl) && null != smallImageCreativeText && !"".equals(smallImageCreativeText)) {
+            JSONObject creative = new JSONObject();
+            creative.put("image_mode", "CREATIVE_IMAGE_MODE_SMALL");
+            Map<String, Object> getImageResult = fileInfoService.uploadImageToBytedance(getAccountId, smallImageUrl);
+            JSONArray imageArray = (JSONArray) getImageResult.get("imageIds");
+            creative.put("image_ids", imageArray);
+            creative.put("title", smallImageCreativeText);
+            creatives.add(creative);
+        }
+
+        //<a-radio-button value="CREATIVE_IMAGE_MODE_LARGE_VERTICAL">大图竖图</a-radio-button>
+        String verticalImageUrl = template.getString("verticalImageUrl");
+        String verticalImageCreativeText = template.getString("verticalImageCreativeText");
+        if (null != verticalImageUrl && !"".equals(verticalImageUrl) && null != verticalImageCreativeText && !"".equals(verticalImageCreativeText)) {
+            JSONObject creative = new JSONObject();
+            creative.put("image_mode", "CREATIVE_IMAGE_MODE_LARGE_VERTICAL");
+//            Map<String,Object> getImageResult = fileInfoService.uploadImageToBytedance(getAccountId,verticalImageUrl);
+//            JSONArray imageArray = (JSONArray) getImageResult.get("imageIds");
+            JSONArray imageArray = new JSONArray();
+            imageArray.add("web.business.image/201908025d0d9292d0662227454294d5");
+            creative.put("image_ids", imageArray);
+            creative.put("title", verticalImageCreativeText);
+            creatives.add(creative);
+        }
+
+
+        data.put("creatives", creatives);
+
+        //应用下载详情页
+        data.put("web_url", template.getString("webUrl"));
+        //应用名
+        data.put("app_name", template.getString("appName"));
+        //广告评论
+        data.put("is_comment_disable ", template.getIntValue("isCommentDisable"));
+        //创意展现方式
+        data.put("creative_display_mode ", template.getString("creativeDisplayMode"));
+        //创意分类
+        JSONArray categorys = template.getJSONArray("adCategory");
+        String thirdIndustryId = categorys.getString(2);
+        data.put("third_industry_id", Integer.parseInt(thirdIndustryId));
+        //创意标签
+        data.put("ad_keywords", template.getJSONArray("adKeywords"));
+        //创意标题
+        data.put("title", "测试创意标题123" + System.currentTimeMillis());
+        return creativeCreate(getAccountId, planId, data.toJSONString());
+    }
+
+    @Autowired
+    private IByteDanceAdvertiserDataService advertiserDataService;
+
     public JSONObject createCreative(JSONObject data, String token) {
 
         // 构造请求

+ 1 - 3
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/ByteDanceUserOrientationTemplateServiceImpl.java

@@ -47,11 +47,9 @@ public class ByteDanceUserOrientationTemplateServiceImpl extends ServiceImpl<Byt
 
     @Override
     public Result<IPage<ByteDanceUserOrientationTemplate>> getList(ByteDanceUserOrientationTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req) {
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
         Result<IPage<ByteDanceUserOrientationTemplate>> result = new Result<>();
         QueryWrapper<ByteDanceUserOrientationTemplate> queryWrapper = QueryGenerator.initQueryWrapper(template, req.getParameterMap());
-        queryWrapper.eq("advertiser_id", token.getAdvertiserId()).orderByDesc("create_time");
+        queryWrapper.orderByDesc("create_time");
         Page<ByteDanceUserOrientationTemplate> page = new Page<>(pageNo, pageSize);
         IPage<ByteDanceUserOrientationTemplate> pageList = this.page(page, queryWrapper);
         result.setSuccess(true);

+ 85 - 27
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/BytedanceAdvertisePlanTemplateServiceImpl.java

@@ -3,10 +3,10 @@ package org.jeecg.modules.ctop.service.impl;
 import com.alibaba.fastjson.JSONObject;
 import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.system.vo.LoginUser;
-import org.jeecg.modules.ctop.entity.ByteDanceBudgetTemplate;
-import org.jeecg.modules.ctop.entity.BytedanceAdvertisePlanTemplate;
-import org.jeecg.modules.ctop.entity.CTopOauthToken;
-import org.jeecg.modules.ctop.mapper.BytedanceAdvertisePlanTemplateMapper;
+import org.jeecg.common.util.ResultMapUtils;
+import org.jeecg.common.util.StatusCode;
+import org.jeecg.modules.ctop.entity.*;
+import org.jeecg.modules.ctop.mapper.*;
 import org.jeecg.modules.ctop.service.IByteDanceAdvertisePlanService;
 import org.jeecg.modules.ctop.service.IBytedanceAdvertisePlanTemplateService;
 import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
@@ -28,37 +28,95 @@ import java.util.Map;
 public class BytedanceAdvertisePlanTemplateServiceImpl extends ServiceImpl<BytedanceAdvertisePlanTemplateMapper, BytedanceAdvertisePlanTemplate> implements IBytedanceAdvertisePlanTemplateService {
 
     @Override
-    public Map<String, Object> insertTemplate(BytedanceAdvertisePlanTemplate template) {
+    public Map<String, Object> insertTemplate(BytedanceAdvertisePlanTemplate template, String accountId) {
         Map<String, Object> resultMap = new HashMap<>();
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
         template.setStatus(1);
         templateMapper.insert(template);
-        //同步线上广告计划信息
-        String accountId = "e9ca23d68d884d4ebb19d07889727dae";
-        Long campaignId = template.getCampaignTemplateId();
-//        ByteDanceBudgetTemplate budgetTemplate = bu
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
+        return resultMap;
+    }
+
+    /**
+     * @param campaignId
+     * @param getAccountId
+     * @param deliveryRange
+     * @param userorentationId
+     * @param budgetId
+     * @param deliverytargetId
+     * @return
+     */
+    @Override
+    public Map<String, Object> planCreate(Long campaignId, String getAccountId, String deliveryRange, Long userorentationId, Long budgetId, Long deliverytargetId, String getName) {
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(getAccountId);
+        ByteDanceBudgetTemplate budgetTemplate = budgetTemplateMapper.selectById(budgetId);
+        BytedanceDeliveryTargetTemplate deliveryTargetTemplate = deliveryTargetTemplateMapper.selectById(deliverytargetId);
+        ByteDanceUserOrientationTemplate userOrientationTemplate = userOrientationTemplateMapper.selectById(userorentationId);
+        ByteDanceCampaign campaign = campaignMapper.selectById(campaignId);
         JSONObject data = new JSONObject();
+        //广告组id
         data.put("campaign_id", campaignId);
-        data.put("delivery_range", "DEFAULT");
-        data.put("budget_mode", "BUDGET_MODE_DAY");
-        data.put("budget", 2000);//需要大于bid
-        data.put("bid", 100);
-        data.put("start_time", "2019-07-30 01:00");
-        data.put("end_time", "2019-07-31 01:00");
-        data.put("pricing", "PRICING_CPM");
-        data.put("schedule_type", "SCHEDULE_FROM_NOW");
-        data.put("flow_control_mode", "FLOW_CONTROL_MODE_FAST");
-        data.put("name", "测试计划名称");
-        data.put("external_url", "https://lordsmobile.176.com/download.php");
-        data.put("download_url", "https://lordsmobile.176.com/download.php");
-        data.put("download_type", "DOWNLOAD_URL");//坑
-        data.put("package", "com.igg.android.lordsmobile_cn");//坑
-        data.put("app_type", "APP_ANDROID");//坑
-        return advertisePlanService.advertiserPlanCreate(accountId, campaignId, data.toJSONString());
+        //投放范围
+        data.put("delivery_range", deliveryRange);
+        //(1):投放目标
+        //投放目标 转化量,点击量,展示量相关 未找到
+//       data.put("")
+        //下载方式 下载链接/落地页链接
+        data.put("download_type", deliveryTargetTemplate.getDownloadType());
+        if (null != deliveryTargetTemplate.getDownloadType() && !"".equals(deliveryTargetTemplate.getDownloadType()) && "DOWNLOAD_URL".equals(deliveryTargetTemplate.getDownloadType())) {
+            //下载链接
+            data.put("download_url", deliveryTargetTemplate.getDownloadUrl());
+            //应用包名
+            data.put("package", deliveryTargetTemplate.getPackageName());
+        }
+
+        if (null != deliveryTargetTemplate.getDownloadType() && !"".equals(deliveryTargetTemplate.getDownloadType()) && "EXTERNAL_URL".equals(deliveryTargetTemplate.getDownloadType())) {
+            //落地页链接
+            data.put("external_url", deliveryTargetTemplate.getExternalUrl());
+        }
+        if (null != campaign.getLandingType() && "APP".equals(campaign.getLandingType()) && null != deliveryTargetTemplate.getDownloadType() && "DOWNLOAD_URL".equals(deliveryTargetTemplate.getDownloadType())) {
+            data.put("app_type", "APP_ANDROID");
+        }
+
+        //(2)人群定向目前空置
+        //(3):预算与出价
+        //广告预算类型 日预算、总预算
+        data.put("budget_mode", budgetTemplate.getBudgetPriceMode());
+        //广告预算
+        data.put("budget", budgetTemplate.getBudgetPrice());//需要大于bid
+        //转化出价(ocpm请填写 cpa_bid)
+        data.put("bid", budgetTemplate.getBudgetPrice());
+        //广告投放时间类型
+        data.put("schedule_type", budgetTemplate.getFlowDateType());
+        //广告投放开始时间
+        data.put("start_time", budgetTemplate.getStartDate());
+        //广告投放结束时间
+        data.put("end_time", budgetTemplate.getEndDate());
+        /**
+         * 广告投放指定时间段
+         * 广告投放时段,默认全时段投放,格式是48*7位字符串,且都是0或1。也就是以半个小时为最小粒度,周一至周日每天分为48个区段,0为不投放,1为投放,不传、全传0、全传1均代表全时段投放。
+         */
+//        data.put("schedule_time", "2019-07-31 01:00");
+        //付费方式
+        data.put("pricing", budgetTemplate.getPriceType());
+        //广告投放速度类型 (投放方式) 优先跑量,均衡投放,优先低成本
+        data.put("flow_control_mode", budgetTemplate.getFlowControlMode());
+        //过滤已转化用户类型 只有投放目标为转化量时,才需要该字段
+        data.put("hide_if_converted", budgetTemplate.getFilterType());
+
+        data.put("name", getName + "_计划_" + System.currentTimeMillis());
+        return advertisePlanService.advertiserPlanCreate(token, campaignId, data.toJSONString());
     }
 
     @Autowired
+    private ByteDanceCampaignMapper campaignMapper;
+    @Autowired
+    private ByteDanceBudgetTemplateMapper budgetTemplateMapper;
+    @Autowired
+    private BytedanceDeliveryTargetTemplateMapper deliveryTargetTemplateMapper;
+    @Autowired
+    private ByteDanceUserOrientationTemplateMapper userOrientationTemplateMapper;
+
+    @Autowired
     private IByteDanceAdvertisePlanService advertisePlanService;
     @Autowired
     private BytedanceAdvertisePlanTemplateMapper templateMapper;

+ 1 - 5
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/BytedanceDeliveryTargetTemplateServiceImpl.java

@@ -34,8 +34,6 @@ public class BytedanceDeliveryTargetTemplateServiceImpl extends ServiceImpl<Byte
     @Override
     public Map<String, Object> insertTemplate(BytedanceDeliveryTargetTemplate template) {
         Map<String, Object> resultMap = new HashMap<>();
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId("74099510334");
         template.setStatus(1);
         deliveryTargetTemplateMapper.insert(template);
         resultMap.put("success", true);
@@ -45,11 +43,9 @@ public class BytedanceDeliveryTargetTemplateServiceImpl extends ServiceImpl<Byte
 
     @Override
     public Result<IPage<BytedanceDeliveryTargetTemplate>> getList(BytedanceDeliveryTargetTemplate template, Integer pageNo, Integer pageSize, HttpServletRequest req) {
-        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(user.getId());
         Result<IPage<BytedanceDeliveryTargetTemplate>> result = new Result<>();
         QueryWrapper<BytedanceDeliveryTargetTemplate> queryWrapper = QueryGenerator.initQueryWrapper(template, req.getParameterMap());
-        queryWrapper.eq("advertiser_id", token.getAdvertiserId()).orderByDesc("create_time");
+        queryWrapper.orderByDesc("create_time");
         Page<BytedanceDeliveryTargetTemplate> page = new Page<>(pageNo, pageSize);
         IPage<BytedanceDeliveryTargetTemplate> pageList = this.page(page, queryWrapper);
         result.setSuccess(true);

+ 399 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/CreateInternalServiceImpl.java

@@ -0,0 +1,399 @@
+package org.jeecg.modules.ctop.service.impl;
+
+import cn.com.ctop.common.utils.Check;
+import cn.com.ctop.common.utils.HttpUtils;
+import cn.com.ctop.crawler.modules.core.util.FateadmHttpUtil;
+import cn.com.ctop.crawler.modules.core.util.FateadmUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.http.impl.cookie.BasicClientCookie;
+import org.jeecg.modules.ctop.service.ICreateInternalService;
+import org.openqa.selenium.Cookie;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import sun.misc.BASE64Decoder;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Service
+public class CreateInternalServiceImpl implements ICreateInternalService {
+    private static final Logger logger = LoggerFactory.getLogger(CreateInternalServiceImpl.class);
+
+
+    @Override
+    public Map<String, Object> createInternal(JSONObject requestJson) {
+        String url = "https://ad.oceanengine.com/pages/login/index.html";
+        System.getProperties().setProperty("webdriver.chrome.driver", "D:/chromedriver.exe");
+//        System.getProperties().setProperty("webdriver.chrome.driver", "/usr/bin/chromedriver");
+        try {
+            ChromeOptions chromeOptions = new ChromeOptions();
+            WebDriver webDriver = new ChromeDriver(chromeOptions);
+            chromeOptions.addArguments("--headless");
+            chromeOptions.addArguments("--incognito");
+            chromeOptions.addArguments("--no-sandbox");
+            chromeOptions.addArguments("--disable-gpu");
+            chromeOptions.addArguments("--window-size=1290,1080");
+            chromeOptions.addArguments("--user-agent=" + HttpUtils.USER_AGENT);
+            chromeOptions.setAcceptInsecureCerts(true);
+            webDriver.get(url);  //获取登录页面
+
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            for (Cookie cookie : webDriver.manage().getCookies()) {
+                BasicClientCookie ck = new BasicClientCookie(cookie.getName(), cookie.getValue());
+                ck.setDomain("ad.oceanengine.com");
+
+
+//                if (cookie.getDomain().startsWith(".")){
+//                    ck.setDomain(cookie.getDomain().substring(1));
+//                }else {
+//                    ck.setDomain(cookie.getDomain());
+//                }
+
+                ck.setExpiryDate(cookie.getExpiry());
+                ck.setPath(cookie.getPath());
+                HttpUtils.cookieStore.addCookie(ck);
+                System.out.println(cookie.getName() + "," + cookie.getValue() + "," + cookie.getDomain());
+
+                BasicClientCookie ck2 = new BasicClientCookie(cookie.getName(), cookie.getValue());
+                ck2.setDomain("toutiao.com");
+
+                ck2.setExpiryDate(cookie.getExpiry());
+                ck2.setPath(cookie.getPath());
+                HttpUtils.cookieStore.addCookie(ck2);
+//                ck.setDomain(".sso.toutiao.com");
+//                HttpUtils.cookieStore.addCookie(ck);
+            }
+
+            String html = webDriver.getPageSource();
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Accept", "*/*");
+            header.put("Connection", "keep-alive");
+            header.put("Host", "sso.toutiao.com");
+            header.put("Content-Type", "application/x-www-form-urlencoded");
+            header.put("Origin", "https://ad.oceanengine.com");
+            header.put("Referer", "https://ad.oceanengine.com/pages/login/index.html");
+            Map<String, Object> param = new HashMap<String, Object>();
+            param.put("mobile", "");
+            param.put("code", "");
+//            param.put("account","guoyanling@c-top.com.cn");
+//            param.put("password","Hcstad-567");
+            param.put("account", "dcd_ad@bytedance.com");
+            param.put("password", "typdDCD@2018");
+            param.put("captcha", "hqde");
+            param.put("is_30_days_no_login", "true");
+            param.put("service", "https://ad.oceanengine.com");
+            String res = HttpUtils.httpPostParamRequest("https://sso.toutiao.com/account_login/", param, header);
+//            System.out.println(res);
+//            Scanner scanner = new Scanner(System.in);
+//            String code = scanner.nextLine();
+//            param.put("captcha",code);
+//            res = HttpUtils.httpPostParamRequest("https://sso.toutiao.com/account_login/",param,header);
+//            System.out.println(res);
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+            JsonNode jsonNode = mapper.readTree(res);
+            Integer errorCode = jsonNode.get("error_code").asInt();
+            String orderId = null;
+            while (errorCode != 0) {
+                FateadmUtil fateadmUtil = new FateadmUtil();
+                fateadmUtil.init();
+                if (orderId != null) {
+                    fateadmUtil.Justice(orderId);
+                }
+                String captcha = jsonNode.get("captcha").asText();
+                BASE64Decoder decoder = new BASE64Decoder();
+                FateadmHttpUtil.HttpResp resp = fateadmUtil.Predict("30400", decoder.decodeBuffer(captcha));
+                param.put("captcha", resp.pred_resl);
+                orderId = resp.req_id;
+                res = HttpUtils.httpPostParamRequest("https://sso.toutiao.com/account_login/", param, header);
+                System.out.println(res);
+                jsonNode = mapper.readTree(res);
+                errorCode = jsonNode.get("error_code").asInt();
+            }
+            if (errorCode == 0) {
+//                String redirectUrl = jsonNode.get("redirect_url").asText();
+//                webDriver.get(redirectUrl);
+                String csrftoken = "";
+                List<org.apache.http.cookie.Cookie> cookies = HttpUtils.cookieStore.getCookies();
+                for (org.apache.http.cookie.Cookie ck : cookies) {
+                    Cookie cookie = new Cookie(ck.getName(), ck.getValue(), "." + ck.getDomain(), ck.getPath(), ck.getExpiryDate());
+                    webDriver.manage().addCookie(cookie);
+                }
+
+                webDriver.get("https://ad.oceanengine.com/pages/promotion.html#/ad");//登录成功 进入推广页面
+
+                webDriver.get("https://ad.oceanengine.com/pages/campaign/create.html");//创建广告组页面
+//                HttpUtils.httpGetRequest("https://ad.toutiao.com/pages/promotion.html#/ad");
+//                HttpUtils.httpGetRequest("https://ad.toutiao.com/pages/campaign/create.html");
+
+                Map<String, Object> param2 = new HashMap<String, Object>();
+                Map<String, Object> param3 = new HashMap<String, Object>();
+                String uuid = UUID.randomUUID().toString();
+                param3.put("budget", 0);
+                param3.put("budget_mode", -1);
+                param2.put("campaign_id", "");
+                param2.put("campaign_name", uuid.substring(1, 7));
+                param2.put("landing_type", 3);
+                param2.put("campaign_type", 1);
+                param2.put("budget", param3);
+
+//                webDriver.get("https://ad.toutiao.com/pages/campaign/create.html");
+                for (Cookie cookie : webDriver.manage().getCookies()) {
+                    if (cookie.getName().equals("csrftoken")) {
+                        csrftoken = cookie.getValue();
+                    }
+                    BasicClientCookie ck = new BasicClientCookie(cookie.getName(), cookie.getValue());
+//                    if (cookie.getDomain().startsWith(".")){
+//                        ck.setDomain(URLDecoder.decode(cookie.getDomain().substring(1),"utf-8"));
+//                    }else {
+//                        ck.setDomain(URLDecoder.decode(cookie.getDomain(),"utf-8"));
+//                    }
+                    ck.setDomain("ad.oceanengine.com");
+
+                    ck.setExpiryDate(cookie.getExpiry());
+                    ck.setPath(cookie.getPath());
+                    HttpUtils.cookieStore.addCookie(ck);
+                    System.out.println(cookie.getName() + "," + cookie.getValue() + "," + cookie.getDomain());
+
+                    BasicClientCookie ck2 = new BasicClientCookie(cookie.getName(), cookie.getValue());
+                    ck2.setDomain("toutiao.com");
+
+                    ck2.setExpiryDate(cookie.getExpiry());
+                    ck2.setPath(cookie.getPath());
+                    HttpUtils.cookieStore.addCookie(ck2);
+                }
+                header.put("Accept", "application/json, text/javascript, */*; q=0.01");
+                header.put("Connection", "keep-alive");
+                header.put("Host", "ad.oceanengine.com");
+                header.put("Content-Type", "application/json");
+                header.put("Origin", "https://ad.oceanengine.com");
+                header.put("X-CSRFToken", csrftoken);
+                header.put("X-Requested-With", "XMLHttpRequest");
+                header.put("Referer", "https://ad.oceanengine.com/pages/campaign/create.html");
+                res = HttpUtils.httpPostRequest("https://ad.oceanengine.com/overture/campaign/create/", param2, header);// 创建广告组返回信息
+                System.out.println(res);
+                JsonNode node = mapper.readTree(res);
+                //{"status": "fail", "msg": "\u5e7f\u544a\u7ec4\u4e0d\u80fd\u91cd\u590d", "type": "form_error", "name": "campaign_name"}
+                String campaignId = node.get("data").get("campaign_id").asText();  //广告组id
+                String url2 = "https://ad.oceanengine.com/pages/ad/create.html?campaign_id=" + campaignId + "&landing_type=3&temp_id=ADvQb";
+                webDriver.get(url2);
+//                webDriver.get("https://ad.toutiao.com/agent/get_agency/?advertiser_id=1634948959249411");
+                header.put("Referer", url2);
+                for (Cookie cookie : webDriver.manage().getCookies()) {
+                    BasicClientCookie ck = new BasicClientCookie(cookie.getName(), cookie.getValue());
+                    ck.setDomain("ad.oceanengine.com");
+
+                    ck.setExpiryDate(cookie.getExpiry());
+                    ck.setPath(cookie.getPath());
+                    HttpUtils.cookieStore.addCookie(ck);
+                    System.out.println(cookie.getName() + "," + cookie.getValue() + "," + cookie.getDomain());
+
+                    BasicClientCookie ck2 = new BasicClientCookie(cookie.getName(), cookie.getValue());
+                    ck2.setDomain("toutiao.com");
+
+                    ck2.setExpiryDate(cookie.getExpiry());
+                    ck2.setPath(cookie.getPath());
+                    HttpUtils.cookieStore.addCookie(ck2);
+                }
+                String siteStr = HttpUtils.httpGetRequest("https://ad.oceanengine.com/overture/api/adv_site/get_site_list/?_=" + String.valueOf(new Date().getTime()));
+                String convStr = HttpUtils.httpGetRequest("https://ad.oceanengine.com/overture/api/get_tetris_action/?external_url=&type=external&pricing=9&landing_type=3&_=" + String.valueOf(new Date().getTime()));
+                JsonNode siteNode = mapper.readTree(siteStr);
+                JsonNode convNode = mapper.readTree(convStr);
+
+                Map<String, Object> param4 = new HashMap<String, Object>();
+                param4.put("location_type", 4);
+                param4.put("aweme_account_fans", 0);
+                String tokenStr = HttpUtils.httpPostRequest("https://ad.oceanengine.com/api/v1/hl/ad/audience/estimate/", param4, header);
+                System.out.println(siteStr);
+                System.out.println(convStr);
+                System.out.println(tokenStr);
+                JsonNode tokenNode = mapper.readTree(tokenStr);
+                Map<String, Object> param5 = new HashMap<String, Object>();
+                /*param5.put("name", "自动创建测试4");  //广计划名称
+                param5.put("delivery_range", 1);  // 投放范围
+                param5.put("classify", 5);  //广告类别  5 内广
+                param5.put("projectid", "");
+                param5.put("download_type", 2);  //下载方式    1下载链接 2包含下载链接的落地页
+                param5.put("localGeolocation", new ArrayList<String>());
+                param5.put("external_url", "https://ad.oceanengine.com/tetris/page/" + siteNode.get("data").get(0).get("siteId").asText());  // 落地页链接
+                param5.put("convert_id", convNode.get("action_data").get(0).get("id").asLong()); // 转换id
+                param5.put("open_url", ""); //  应用直达链接
+                param5.put("style_type", 0);
+                param5.put("location_type", 4); //受众位置类型
+                param5.put("hide_if_exists", 0); // 过滤已安装,当推广目标为安卓应用下载时可填,0表示不过滤,1表示过滤,默认为不过滤
+                param5.put("interest_tag_mode", 0); //兴趣分类
+                param5.put("token", tokenNode.get("data").get("token").asText());
+                param5.put("toutiao", 100000005);  //头条预估数据
+                param5.put("aweme", 150000005); //抖音预估数据
+                param5.put("video_app", 40000005);//西瓜预估数据
+                param5.put("hotsoon", 40000005); //火山预估数据
+                param5.put("aweme_account_fans", 0); //账号粉丝相似人群
+                param5.put("auto_extend_enabled", 0);// 智能放量????
+                param5.put("budget_mode", 0);  // 广告预算类型  0 日预算  1 总预算
+                param5.put("budget", 300); //广告预算
+                param5.put("schedule_type", 1); //广告投放时间类型   默认1 1:不限  2:按时间???
+                param5.put("start_time", "2019-07-02 00:00"); //广告投放起始时间
+                param5.put("end_time", "2019-07-03 23:59");//广告投放结束时间
+                param5.put("week_schedule", new ArrayList<String>());  //投放时段
+                param5.put("week_time", new ArrayList<ArrayList<Integer>>());//投放时段
+                param5.put("pricing", 9); //计划出价类型  9 按展示付费  7 按点击付费 8 按转化付费
+                param5.put("cpa_phrase", 2); //出价为OCPC时,计划处于哪个阶段??
+                param5.put("is_union_slot", "");
+                param5.put("hide_if_converted", 1); //过滤已转化用户类型字段,只有转化为目标时可填 优化目标为转化才展示
+                param5.put("flow_control_mode", 0); //投放速度/投放方式使用字段
+                param5.put("cpa_bid", 1);
+                param5.put("smart_bid_type", 0); //自动出价类型,OCPM支持
+                param5.put("adjust_cpa", 0); //是否调整自动出价   允许值: "0", "1"  默认值: 0
+                param5.put("app_bid_ratio", new Object());
+                param5.put("campaign_id", campaignId);*/
+
+
+//                param5.put("name", requestJson.getString("templateName"));  //广计划名称
+               /* param5.put("name", param2.get("campaign_name"));
+                param5.put("delivery_range", requestJson.getInteger("deliveryRange"));  // 投放范围
+                param5.put("classify", requestJson.getInteger("adCategory"));  //广告类别  5 内广
+                param5.put("projectid", "");
+                //     param5.put("target", requestJson.getString("deliveryTarget")); //投放目标
+                param5.put("download_type", requestJson.getInteger("downloadType"));  //下载方式    1下载链接 2包含下载链接的落地页
+                param5.put("localGeolocation", new ArrayList<String>());
+
+                String downloadUrl = "";
+                if (!Check.isNull(requestJson.getString("downloadUrl"))) {
+                    downloadUrl = requestJson.getString("downloadUrl");
+                } else {
+                    downloadUrl = requestJson.getString("externalUrl");
+                }
+
+                //   param5.put("external_url", downloadUrl);  // 落地页链接
+                param5.put("download_url", downloadUrl);  // 下载链接
+                param5.put("package", "com.prometheus.c6");  // 包
+                param5.put("app_type", 201);  // app類型
+                //      param5.put("convert_id", convNode.get("action_data").get(0).get("id").asLong()); // 转换id
+                param5.put("open_url", ""); //  应用直达链接
+                param5.put("style_type", 0);
+                param5.put("location_type", 4); //受众位置类型
+                param5.put("hide_if_exists", 0); // 过滤已安装,当推广目标为安卓应用下载时可填,0表示不过滤,1表示过滤,默认为不过滤
+                param5.put("interest_tag_mode", 0); //兴趣分类
+                param5.put("token", tokenNode.get("data").get("token").asText());
+                param5.put("toutiao", 100000005);  //头条预估数据
+                param5.put("aweme", 150000005); //抖音预估数据
+                param5.put("video_app", 40000005);//西瓜预估数据
+                param5.put("hotsoon", 40000005); //火山预估数据
+                param5.put("aweme_account_fans", 0); //账号粉丝相似人群
+                param5.put("auto_extend_enabled", 0);// 智能放量????
+                param5.put("budget_mode", 0);  // 广告预算类型  0 日预算  1 总预算
+                param5.put("budget", requestJson.getString("budgetPrice")); //广告预算
+
+
+                String flowDateType = requestJson.getString("flowDateType");
+                param5.put("schedule_type", 1); //广告投放时间类型   默认1 1:不限  2:按时间???
+                System.err.println(requestJson.getString("startDate"));
+                System.err.println(requestJson.getString("endDate"));
+                param5.put("start_time", "2019-08-03 23:59"); //广告投放起始时间
+                param5.put("end_time", "2019-08-04 23:59");//广告投放结束时间
+
+                List<List<String>> wsList = new ArrayList<List<String>>();
+                wsList.add(new ArrayList<String>());
+                wsList.add(new ArrayList<String>());
+                wsList.add(new ArrayList<String>());
+                wsList.add(new ArrayList<String>());
+                wsList.add(new ArrayList<String>());
+                wsList.add(new ArrayList<String>());
+                wsList.add(new ArrayList<String>());
+                param5.put("week_schedule", wsList);  //投放时段
+                param5.put("week_time", new ArrayList<ArrayList<Integer>>());//投放时段
+                param5.put("pricing", requestJson.getString("priceType")); //计划出价类型  9 按展示付费  7 按点击付费 8 按转化付费
+                param5.put("cpa_phrase", 2); //出价为OCPC时,计划处于哪个阶段??
+                param5.put("is_union_slot", "");
+                param5.put("hide_if_converted", 1); //过滤已转化用户类型字段,只有转化为目标时可填 优化目标为转化才展示
+                param5.put("flow_control_mode", 0); //投放速度/投放方式使用字段
+
+
+                param5.put("smart_bid_type", 0); //自动出价类型,OCPM支持
+                param5.put("adjust_cpa", 0); //是否调整自动出价   允许值: "0", "1"  默认值: 0
+                param5.put("app_bid_ratio", new Object());
+                param5.put("cpa_bid", 1);//目标转化出价
+                param5.put("external_action", 4);//
+                param5.put("android_osv", 0);//
+                List list = new ArrayList();
+                list.add(1);
+
+                param5.put("platform", list);//
+                param5.put("campaign_id", campaignId);*/
+
+                param5.put("name", requestJson.getString("templateName"));//模板名称
+                Integer deliveryRange = requestJson.getInteger("deliveryRange");
+                param5.put("delivery_range", deliveryRange);  //投放形式
+
+                if (deliveryRange == 2) {
+                    param5.put("union_video_type", requestJson.getInteger("deliveryForm")); //投放形式 1:激励视频 2:原生
+                }
+
+                param5.put("classify", requestJson.getString("adCategory")); //广告类别
+                param5.put("projectid", ""); //
+                Integer downloadType = requestJson.getInteger("downloadType");
+                param5.put("download_type", downloadType); //下载方式  1:下载包 2:h5
+                if (downloadType == 1) {
+                    param5.put("download_url",requestJson.getString("downloadUrl"));
+                }
+                if(downloadType == 2 ){
+                    param5.put("external_url", requestJson.getString("externalUrl"));  // 落地页链接
+                }
+
+                param5.put("localGeolocation", new ArrayList<String>());
+                param5.put("package", requestJson.getString("packageName"));//包名
+                param5.put("style_type", 0); //样式类型
+                param5.put("location_type", 4); //受众位置类型
+                param5.put("hide_if_exists", 0); // 过滤已安装,当推广目标为安卓应用下载时可填,0表示不过滤,1表示过滤,默认为不过滤
+                param5.put("interest_tag_mode", 0); //兴趣分类
+                param5.put("token", tokenNode.get("data").get("token").asText());
+                param5.put("toutiao", 100000005);
+                param5.put("aweme", 150000005);
+                param5.put("video_app", 40000005);
+                param5.put("hotsoon", 40000005);
+                param5.put("aweme_account_fans", 0);
+                param5.put("auto_extend_enabled", 0);
+                param5.put("budget_mode", 0); //预算类型 0 日预算  1 总预算
+                param5.put("budget", 300); //预算金额
+                param5.put("app_type", 201); //app 类型 201 应用推广 安卓 201 应用推广 ios
+                param5.put("schedule_type", 1); //广告投放时间类型   默认1 1:不限  2:按时间???
+                param5.put("start_time", "2019-09-02 00:00"); // 广告投放开始时间
+                param5.put("end_time", "2019-09-03 23:59"); //结束时间
+                param5.put("week_schedule", new ArrayList<String>());
+                param5.put("week_time", new ArrayList<ArrayList<Integer>>());
+                param5.put("pricing", requestJson.getString("priceType")); ////计划出价类型  9 按展示付费  7 按点击付费 8 按转化付费
+                param5.put("cpa_phrase", 2);
+                param5.put("is_union_slot", "");
+                param5.put("hide_if_converted", 1); //过滤已转化用户类型字段,只有转化为目标时可填 优化目标为转化才展示
+                param5.put("flow_control_mode", 0); //投放速度/投放方式使用字段
+                param5.put("cpa_bid", 1); //目标转化出价
+                param5.put("smart_bid_type", 0); ////自动出价类型,OCPM支持
+
+                param5.put("external_action", 15);
+                param5.put("adjust_cpa", 0); ////是否调整自动出价   允许值: "0", "1"  默认值: 0
+                param5.put("app_bid_ratio", new Object());
+
+                param5.put("campaign_id", campaignId);
+
+                System.err.println(JSON.toJSONString(param5));
+                String createResult = HttpUtils.httpPostRequest("https://ad.oceanengine.com/overture/ad/create/", param5, header);
+                System.out.println(createResult);
+            }
+//            webDriver.close();
+
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+}

+ 139 - 69
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/service/impl/FileInfoServiceImpl.java

@@ -1,7 +1,13 @@
 package org.jeecg.modules.ctop.service.impl;
 
 import cn.com.ctop.common.utils.PropertiesUtils;
+import cn.com.ctop.toutiao.common.BytedanceInterfaceConstant;
+import com.alibaba.druid.support.spring.stat.annotation.Stat;
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.http.HttpEntity;
@@ -15,23 +21,29 @@ import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.entity.mime.content.FileBody;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
-import org.jeecg.modules.ctop.entity.ByteDanceImageInfo;
-import org.jeecg.modules.ctop.entity.ByteDanceVideoInfo;
-import org.jeecg.modules.ctop.entity.CTopOauthToken;
-import org.jeecg.modules.ctop.entity.FileInfo;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.ResultMapUtils;
+import org.jeecg.common.util.StatusCode;
+import org.jeecg.modules.ctop.entity.*;
 import org.jeecg.modules.ctop.mapper.ByteDanceImageInfoMapper;
 import org.jeecg.modules.ctop.mapper.ByteDanceVideoInfoMapper;
 import org.jeecg.modules.ctop.mapper.FileInfoMapper;
 import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
 import org.jeecg.modules.ctop.service.IFileInfoService;
+import org.jeecg.modules.system.entity.SysCategory;
+import org.jeecg.modules.system.mapper.SysCategoryMapper;
+import org.jeecg.modules.system.service.ISysCategoryService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.servlet.http.HttpServletRequest;
 import java.io.*;
 import java.net.URI;
+import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -45,31 +57,54 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
     private static final Logger logger = LoggerFactory.getLogger(FileInfoServiceImpl.class);
 
     @Override
-    public Map<String, Object> uploadVideoToTemplate(String accountId, Long videoFileId, String templatename) {
+    public Map<String, Object> uploadVideoToBytedance(String accountId, String videoUrl) {
         Map<String, Object> resultMap = new HashMap<>();
-        FileInfo fileInfo = fileInfoMapper.selectById(videoFileId);
-        if (null == fileInfo) {
-            resultMap.put("message", "该视频文件信息不存在");
-            resultMap.put("code", -1);
-            return resultMap;
-        }
         //TODO查询是否已经上传过头条平台
         CTopOauthToken token = tokenService.getOAuthTokenByAccountId(accountId);
-        JSONObject resultObject = uploadAdvideo(token.getAccessToken(), fileInfo, token.getAccountId() + "");
+        JSONObject resultObject = uploadAdvideo(token.getAccessToken(), videoUrl, token.getAccountId() + "");
         System.out.println(resultObject);
         Integer code = resultObject.getInteger("code");
         String message = resultObject.getString("message");
         if (null == code || code != 0) {
             logger.info("视频文件上传失败,accountId:{},message:{}", accountId, message);
-            resultMap.put("code", -1);
-            resultMap.put("message", "视频文件上传失败");
+            ResultMapUtils.setResultMap(resultMap, StatusCode.BYTEDANCE_VIDEO_UPLOAD_FAIL.getCode());
             return resultMap;
         }
         JSONObject data = resultObject.getJSONObject("data");
-        ByteDanceVideoInfo videoInfo = new ByteDanceVideoInfo(data, token, videoFileId);
+        ByteDanceVideoInfo videoInfo = new ByteDanceVideoInfo(data, token);
         videoInfoMapper.insert(videoInfo);
-        resultMap.put("code", 0);
-        resultMap.put("message", "视频文件上传成功");
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
+        resultMap.put("videoId", videoInfo.getId());
+        return resultMap;
+    }
+
+    @Override
+    public Map<String, Object> upload3ImagesToBytedance(String accountId, String imageFileUrls) {
+        Map<String, Object> resultMap = new HashMap<>();
+        String[] imageUrls = imageFileUrls.split(",");
+        if (null == imageUrls || imageUrls.length < 3) {
+            ResultMapUtils.setResultMap(resultMap, StatusCode.IMAGE_NUMBER_SHORTAGE.getCode());
+            return resultMap;
+        }
+        CTopOauthToken token = tokenService.getOAuthTokenByAccountId(accountId);
+        JSONArray imageIds = new JSONArray();
+        for (int i = 0; i < imageUrls.length; i++) {
+            JSONObject resultObject = uploadAdImage(token.getAccessToken(), imageUrls[i], token.getAccountId() + "");
+            System.out.println(resultObject);
+            Integer code = resultObject.getInteger("code");
+            String message = resultObject.getString("message");
+            if (null == code || code != 0) {
+                logger.info("图片文件上传失败,accountId:{},message:{}", accountId, message);
+                ResultMapUtils.setResultMap(resultMap, StatusCode.BYTEDANCE_VIDEO_UPLOAD_FAIL.getCode());
+                return resultMap;
+            }
+            JSONObject data = resultObject.getJSONObject("data");
+            ByteDanceVideoInfo videoInfo = new ByteDanceVideoInfo(data, token);
+            videoInfoMapper.insert(videoInfo);
+            imageIds.add(videoInfo.getId());
+        }
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
+        resultMap.put("imageIds", imageIds);
         return resultMap;
     }
 
@@ -79,54 +114,99 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
     private ByteDanceImageInfoMapper imageInfoMapper;
 
     @Override
-    public Map<String, Object> uploadImageToTemplate(String accountId, Long imageFileId, String templatename) {
+    public Map<String, Object> uploadImageToBytedance(String accountId, String imageUrl) {
         Map<String, Object> resultMap = new HashMap<>();
-        FileInfo fileInfo = fileInfoMapper.selectById(imageFileId);
-        if (null == fileInfo) {
-            resultMap.put("message", "该图片文件信息不存在");
-            resultMap.put("code", -1);
-            return resultMap;
-        }
-        if (null == fileInfo.getType() || !"IMAGE".equals(fileInfo.getType())) {
-            resultMap.put("message", "文件格式错误");
-            resultMap.put("code", -1);
-            return resultMap;
-        }
-        //TODO查询是否已经上传过头条平台
         CTopOauthToken token = tokenService.getOAuthTokenByAccountId(accountId);
-        JSONObject resultObject = uploadAdImage(token.getAccessToken(), fileInfo, token.getAccountId() + "");
-        System.out.println(resultObject);
+        JSONObject resultObject = uploadAdImage(token.getAccessToken(), imageUrl, token.getAccountId() + "");
         Integer code = resultObject.getInteger("code");
         String message = resultObject.getString("message");
         if (null == code || code != 0) {
             logger.info("图片文件上传失败,accountId:{},message:{}", accountId, message);
-            resultMap.put("code", -1);
-            resultMap.put("message", "图片文件上传失败");
+            ResultMapUtils.setResultMap(resultMap, StatusCode.BYTEDANCE_IMAGE_UPLOAD_FAIL.getCode());
             return resultMap;
         }
         JSONObject data = resultObject.getJSONObject("data");
-        ByteDanceImageInfo imageInfo = new ByteDanceImageInfo(data, token, imageFileId);
+        ByteDanceImageInfo imageInfo = new ByteDanceImageInfo(data, token);
         imageInfoMapper.insert(imageInfo);
-        resultMap.put("code", 0);
-        resultMap.put("message", "图片文件上传成功");
+        ResultMapUtils.setResultMap(resultMap, StatusCode.COMMON_SUCCESS.getCode());
+        JSONArray array = new JSONArray();
+        array.add(imageInfo.getId());
+        resultMap.put("imageIds", array);
         return resultMap;
     }
 
     @Override
-    public Map<String, Object> getIndustryList(String accountId) {
+    public Map<String, Object> getIndustryList(String accountId, Integer level) {
         Map<String, Object> resultMap = new HashMap<>();
         CTopOauthToken token = tokenService.getOAuthTokenByAccountId(accountId);
-        JSONObject result = searchIndustry(token);
+        JSONObject result = searchIndustry(token, level);
+        JSONArray list = result.getJSONObject("data").getJSONArray("list");
+        for (int i = 0; i < list.size(); i++) {
+            JSONObject object = list.getJSONObject(i);
+            SysCategory category = new SysCategory();
+            String firstCode = object.getInteger("second_industry_id") + "";
+            QueryWrapper<SysCategory> wrapper = new QueryWrapper();
+            wrapper.eq("code", firstCode);
+            SysCategory parent = sysCategoryMapper.selectOne(wrapper);
+            category.setPid(parent.getId());
+            category.setName(object.getString("third_industry_name"));
+            category.setCode(object.getInteger("third_industry_id") + "");
+            category.setCreateBy("admin");
+            category.setCreateTime(new Date());
+            category.setSysOrgCode("A01");
+            sysCategoryMapper.insert(category);
+        }
         resultMap.put("code", 0);
         resultMap.put("message", "数据获取成功");
         resultMap.put("data", result);
         return resultMap;
     }
 
-    public JSONObject searchIndustry(CTopOauthToken token) {
+    @Override
+    public JSONArray getByteDanceIndustryList(HttpServletRequest req) {
+        JSONArray result = new JSONArray();
+        String pid = "6c6b0ad4f49b65f3943528e8a35d74fc";
+        List<SysCategory> categories = categoryService.getListByPid(pid);
+        for (SysCategory category : categories) {
+            JSONObject object = new JSONObject();
+            object.put("value", category.getCode());
+            object.put("label", category.getName());
+            JSONArray childListArray = new JSONArray();
+            List<SysCategory> childList = categoryService.getListByPid(category.getId());
+            for (SysCategory child : childList) {
+                JSONObject childObject = new JSONObject();
+                childObject.put("value", child.getCode());
+                childObject.put("label", child.getName());
+                JSONArray secendChildListArray = new JSONArray();
+                List<SysCategory> secendChildList = categoryService.getListByPid(child.getId());
+                for (SysCategory secendChild : secendChildList) {
+                    JSONObject secendChildObject = new JSONObject();
+                    secendChildObject.put("value", secendChild.getCode());
+                    secendChildObject.put("label", secendChild.getName());
+                    secendChildListArray.add(secendChildObject);
+                }
+                childObject.put("children", secendChildListArray);
+                childListArray.add(childObject);
+            }
+            object.put("children", childListArray);
+            result.add(object);
+        }
+        return result;
+    }
+
+
+    @Autowired
+    private ISysCategoryService categoryService;
+
+    @Autowired
+    private SysCategoryMapper sysCategoryMapper;
+
+    public JSONObject searchIndustry(CTopOauthToken token, Integer level) {
         // 请求地址
         String url = "https://ad.toutiao.com/open_api/2/tools/industry/get/";
-
+        if (null != level) {
+            url += "?level=" + level;
+        }
         // 构造请求
         HttpEntityEnclosingRequestBase httpEntity = new HttpEntityEnclosingRequestBase() {
             @Override
@@ -169,22 +249,18 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
         return null;
     }
 
-    public JSONObject uploadAdImage(String accessToken, FileInfo fileInfo, String advertiserId) {
+    public JSONObject uploadAdImage(String accessToken, String imageUrl, String advertiserId) {
         // 请求地址
         String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_file_image_ad");
         // 构造请求
         HttpPost httpPost = new HttpPost(url);
         httpPost.setHeader("Access-Token", accessToken);
-        // 文件参数
-        FileBody file = new FileBody(new File(fileInfo.getPath()));
-        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create().addPart("image_file", file);
+        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
         // 其他参数
         entityBuilder.addTextBody("advertiser_id", advertiserId);
-        try {
-            entityBuilder.addTextBody("image_signature", DigestUtils.md5Hex(new FileInputStream(fileInfo.getPath())));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+        entityBuilder.addTextBody("upload_type", BytedanceInterfaceConstant.UPLOAD_TYPE_BY_URL);
+        entityBuilder.addTextBody("image_url", "https:" + imageUrl);
+
         HttpEntity entity = entityBuilder.build();
         CloseableHttpResponse response = null;
         CloseableHttpClient client = null;
@@ -220,26 +296,25 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
         return null;
     }
 
-    public JSONObject uploadAdvideo(String accessToken, FileInfo fileInfo, String advertiserId) {
+    public JSONObject uploadAdvideo(String accessToken, String videoUrl, String advertiserId) {
+        CloseableHttpResponse response = null;
+        CloseableHttpClient client = null;
         // 请求地址
         String url = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url") + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_file_video_ad");
         // 构造请求
         HttpPost httpPost = new HttpPost(url);
         httpPost.setHeader("Access-Token", accessToken);
         // 文件参数
-        FileBody file = new FileBody(new File(fileInfo.getPath()));
-        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create().addPart("video_file", file);
-        // 其他参数
-        entityBuilder.addTextBody("advertiser_id", advertiserId);
-        try {
-            entityBuilder.addTextBody("video_signature", DigestUtils.md5Hex(new FileInputStream(fileInfo.getPath())));
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        HttpEntity entity = entityBuilder.build();
-        CloseableHttpResponse response = null;
-        CloseableHttpClient client = null;
         try {
+            videoUrl = "https:" + videoUrl;
+            URI uri = new URI(videoUrl);
+            FileBody file = new FileBody(new File(uri));
+            MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create().addPart("video_file", file);
+            // 其他参数
+            entityBuilder.addTextBody("advertiser_id", advertiserId);
+            //TODO 需要后期优化修改代码逻辑
+            entityBuilder.addTextBody("image_signature", DigestUtils.md5Hex(new FileInputStream(new File(uri))));
+            HttpEntity entity = entityBuilder.build();
             client = HttpClientBuilder.create().build();
             httpPost.setURI(URI.create(url));
             httpPost.setEntity(entity);
@@ -254,9 +329,7 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
                 bufferedReader.close();
                 return JSONObject.parseObject(result.toString());
             }
-        } catch (ClientProtocolException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
@@ -270,9 +343,6 @@ public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> i
         }
         return null;
     }
-
-    @Autowired
-    private FileInfoMapper fileInfoMapper;
     @Autowired
     private ICTopOauthTokenService tokenService;
 }

+ 2 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java

@@ -22,6 +22,8 @@ public interface ISysCategoryService extends IService<SysCategory> {
 	void addSysCategory(SysCategory sysCategory);
 	
 	void updateSysCategory(SysCategory sysCategory);
+
+    List<SysCategory> getListByPid(String pid);
 	
 	/**
 	  * 根据父级编码加载分类字典的数据

+ 13 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java

@@ -2,6 +2,10 @@ package org.jeecg.modules.system.service.impl;
 
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.jeecg.common.constant.CacheConstant;
 import org.jeecg.common.exception.JeecgBootException;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.system.entity.SysCategory;
@@ -52,6 +56,15 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
 		baseMapper.updateById(sysCategory);
 	}
 
+    @Override
+    public List<SysCategory> getListByPid(String pid) {
+        QueryWrapper<SysCategory> wrapper = new QueryWrapper<>();
+        wrapper.eq("pid", pid).orderByDesc("create_time");
+        Page<SysCategory> page = new Page<>(1, 1000);
+        IPage<SysCategory> pageList = this.page(page, wrapper);
+        return pageList.getRecords();
+    }
+
 	@Override
 	public List<TreeSelectModel> queryListByCode(String pcode) throws JeecgBootException{
 		String pid = ROOT_PID_VALUE;

+ 37 - 0
module-common/src/main/java/cn/com/ctop/common/utils/HttpUtils.java

@@ -150,6 +150,43 @@ public class HttpUtils {
     }
 
 
+    public static String httpPostRequestTest(String url, String body, Map<String, String> headers) {
+//        HttpClient httpclient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
+        HttpClient httpClient = createSSLClientDefault();
+        String strReturn = "";
+        try {
+            HttpPost httppost = new HttpPost(url);
+            httppost.setHeader("User-Agent", USER_AGENT);
+            httppost.addHeader("Content-Type", "application/json");
+            List<Cookie> list = cookieStore.getCookies();
+            for (Cookie ck : list) {
+                System.out.println(ck.getName() + "=" + ck.getValue() + "," + ck.getDomain());
+            }
+            for (String key : headers.keySet()) {
+                httppost.setHeader(key, headers.get(key));
+            }
+            //httppost.setHeader("Content-Type", "application/json");
+            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();
+            logger.error(e.getMessage());
+        }
+        return strReturn;
+    }
+
+
     public static String kuaiShouhttpPostRequest(String url, String body, Map<String, String> headers) {
         HttpClient httpClient = createSSLClientDefault();
         String strReturn = "";

+ 3 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/common/BytedanceInterfaceConstant.java

@@ -6,4 +6,7 @@ public class BytedanceInterfaceConstant {
     public static final String REFRESH_TOKEN = "/oauth2/refresh_token";
     public static final String ADVERTISER_INFO = "/2/advertiser/info";
 
+    public static final String UPLOAD_TYPE_BY_FILE = "UPLOAD_BY_FILE";
+    public static final String UPLOAD_TYPE_BY_URL = "UPLOAD_BY_URL";
+
 }

+ 38 - 48
module-toutiao/src/main/java/cn/com/ctop/toutiao/test/Test.java

@@ -39,7 +39,7 @@ public class Test {
             chromeOptions.addArguments("--window-size=1290,1080");
             chromeOptions.addArguments("--user-agent="+HttpUtils.USER_AGENT);
             chromeOptions.setAcceptInsecureCerts(true);
-            webDriver.get(url);
+            webDriver.get(url);  //获取登录页面
 
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
             for (Cookie cookie : webDriver.manage().getCookies()){
@@ -72,8 +72,8 @@ public class Test {
             param.put("code","");
 //            param.put("account","guoyanling@c-top.com.cn");
 //            param.put("password","Hcstad-567");
-            param.put("account", "touxitouxi00075@bytedance.com");
-            param.put("password", "Youxi,2018");
+            param.put("account","dcd_ad@bytedance.com");
+            param.put("password","typdDCD@2018");
             param.put("captcha","hqde");
             param.put("is_30_days_no_login","true");
             param.put("service","https://ad.oceanengine.com");
@@ -115,9 +115,9 @@ public class Test {
                     webDriver.manage().addCookie(cookie);
                 }
 
-                webDriver.get("https://ad.oceanengine.com/pages/promotion.html#/ad");
-                Thread.sleep(10000);
-                webDriver.get("https://ad.oceanengine.com/pages/campaign/create.html");
+                webDriver.get("https://ad.oceanengine.com/pages/promotion.html#/ad");//登录成功 进入推广页面
+
+                webDriver.get("https://ad.oceanengine.com/pages/campaign/create.html");//创建广告组页面
 //                HttpUtils.httpGetRequest("https://ad.toutiao.com/pages/promotion.html#/ad");
 //                HttpUtils.httpGetRequest("https://ad.toutiao.com/pages/campaign/create.html");
 
@@ -126,7 +126,7 @@ public class Test {
                 param3.put("budget",0);
                 param3.put("budget_mode",-1);
                 param2.put("campaign_id","");
-                param2.put("campaign_name", "自动创建测试14");
+                param2.put("campaign_name","自动创建测试444444");
                 param2.put("landing_type",3);
                 param2.put("campaign_type",1);
                 param2.put("budget",param3);
@@ -156,11 +156,11 @@ public class Test {
                 header.put("X-CSRFToken",csrftoken);
                 header.put("X-Requested-With","XMLHttpRequest");
                 header.put("Referer","https://ad.oceanengine.com/pages/campaign/create.html");
-                res = HttpUtils.httpPostRequest("https://ad.oceanengine.com/overture/campaign/create/",param2,header);
+                res = HttpUtils.httpPostRequest("https://ad.oceanengine.com/overture/campaign/create/",param2,header);// 创建广告组返回信息
                 System.out.println(res);
                 JsonNode node = mapper.readTree(res);
                 //{"status": "fail", "msg": "\u5e7f\u544a\u7ec4\u4e0d\u80fd\u91cd\u590d", "type": "form_error", "name": "campaign_name"}
-                String campaignId = node.get("data").get("campaign_id").asText();
+                String campaignId = node.get("data").get("campaign_id").asText();  //广告组id
                 String url2 = "https://ad.oceanengine.com/pages/ad/create.html?campaign_id="+campaignId+"&landing_type=3&temp_id=ADvQb";
                 webDriver.get(url2);
 //                webDriver.get("https://ad.toutiao.com/agent/get_agency/?advertiser_id=1634948959249411");
@@ -187,52 +187,42 @@ public class Test {
                 System.out.println(tokenStr);
                 JsonNode tokenNode = mapper.readTree(tokenStr);
                 Map<String,Object> param5 = new HashMap<String,Object>();
-                param5.put("delivery_range",1);
-                param5.put("classify",5);
+                param5.put("delivery_range",1);  // 投放范围
+                param5.put("classify",5);  //广告类别  5 内广
                 param5.put("projectid","");
-                param5.put("download_type", 1);
-//                param5.put("download_type",2);
+                param5.put("download_type",2);  //下载方式    1下载链接 2包含下载链接的落地页
                 param5.put("localGeolocation",new ArrayList<String>());
-//                param5.put("external_url", "https://ad.oceanengine.com/tetris/page/1");
-//                param5.put("convert_id", 1637294570512391L);
-//                param5.put("external_url","https://ad.oceanengine.com/tetris/page/"+siteNode.get("data").get(0).get("siteId").asText());
-//                param5.put("convert_id",convNode.get("action_data").get(0).get("id").asLong());
-                param5.put("open_url","");
+                param5.put("external_url","https://ad.oceanengine.com/tetris/page/"+siteNode.get("data").get(0).get("siteId").asText());  // 落地页链接
+                param5.put("convert_id",convNode.get("action_data").get(0).get("id").asLong()); // 转换id
+                param5.put("open_url",""); //  应用直达链接
                 param5.put("style_type",0);
-                param5.put("location_type",4);
-                param5.put("hide_if_exists",0);
-                param5.put("interest_tag_mode",0);
+                param5.put("location_type",4); //受众位置类型
+                param5.put("hide_if_exists",0); // 过滤已安装,当推广目标为安卓应用下载时可填,0表示不过滤,1表示过滤,默认为不过滤
+                param5.put("interest_tag_mode",0); //兴趣分类
                 param5.put("token",tokenNode.get("data").get("token").asText());
-                param5.put("toutiao",100000005);
-                param5.put("aweme",150000005);
-                param5.put("video_app",40000005);
-                param5.put("hotsoon",40000005);
-                param5.put("aweme_account_fans",0);
-                param5.put("auto_extend_enabled",0);
-                param5.put("budget_mode",0);
-                param5.put("budget",300);
-                param5.put("app_type", 201);
-                param5.put("schedule_type",1);
-                param5.put("start_time", "2019-09-02 00:00");
-                param5.put("end_time", "2019-09-03 23:59");
-                param5.put("week_schedule",new ArrayList<String>());
-                param5.put("week_time",new ArrayList<ArrayList<Integer>>());
-                param5.put("pricing",9);
-                param5.put("cpa_phrase",2);
+                param5.put("toutiao",100000005);  //头条预估数据
+                param5.put("aweme",150000005); //抖音预估数据
+                param5.put("video_app",40000005);//西瓜预估数据
+                param5.put("hotsoon",40000005); //火山预估数据
+                param5.put("aweme_account_fans",0); //账号粉丝相似人群
+                param5.put("auto_extend_enabled",0);// 智能放量????
+                param5.put("budget_mode",0);  // 广告预算类型  0 日预算  1 总预算
+                param5.put("budget",300); //广告预算
+                param5.put("schedule_type",1); //广告投放时间类型   默认1 1:不限  2:按时间???
+                param5.put("start_time","2019-07-02 00:00"); //广告投放起始时间
+                param5.put("end_time","2019-07-03 23:59");//广告投放结束时间
+                param5.put("week_schedule",new ArrayList<String>());  //投放时段
+                param5.put("week_time",new ArrayList<ArrayList<Integer>>());//投放时段
+                param5.put("pricing",9); //计划出价类型  9 按展示付费  7 按点击付费 8 按转化付费
+                param5.put("cpa_phrase",2); //出价为OCPC时,计划处于哪个阶段??
                 param5.put("is_union_slot","");
-                param5.put("hide_if_converted",1);
-                param5.put("flow_control_mode",0);
+                param5.put("hide_if_converted",1); //过滤已转化用户类型字段,只有转化为目标时可填 优化目标为转化才展示
+                param5.put("flow_control_mode",0); //投放速度/投放方式使用字段
                 param5.put("cpa_bid",1);
-                param5.put("smart_bid_type",0);
-                param5.put("download_url", "https://download.dgstaticresources.net/fusion/android/app-c6-release.apk");
-                param5.put("package", "com.prometheus.c6");
-                param5.put("external_action", 15);
-//                param5.put("convert_id","com.cjijh.yuy");
-//                param5.put("external_actions","com.cjijh.yuy"
-//                );
-                param5.put("adjust_cpa",0);
+                param5.put("smart_bid_type",0); //自动出价类型,OCPM支持
+                param5.put("adjust_cpa",0); //是否调整自动出价   允许值: "0", "1"  默认值: 0
                 param5.put("app_bid_ratio",new Object());
-                param5.put("name", "自动创建测试14");
+                param5.put("name","自动创建测试4");  //广计划名称
                 param5.put("campaign_id",campaignId);
                 String createResult = HttpUtils.httpPostRequest("https://ad.oceanengine.com/overture/ad/create/",param5,header);
                 System.out.println(createResult);