Ver código fonte

计划、组、创意创建

liyuyi@c-top.com.cn 4 anos atrás
pai
commit
b1114d8036

+ 238 - 13
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ads/service/impl/AiStrategyServiceImpl.java

@@ -1,24 +1,37 @@
 package org.jeecg.modules.ads.service.impl;
 
 import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.entity.MaterialCutFrame;
+import cn.com.ctop.common.module.entity.MaterialImageInfo;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.service.IMaterialCutFrameService;
+import cn.com.ctop.common.module.service.IMaterialImageInfoService;
 import cn.com.ctop.common.module.service.IOauthAgentTokenService;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouStrategy;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouMaterialUploadService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.sun.mail.imap.protocol.INTERNALDATE;
 import groovy.util.logging.Slf4j;
 import org.jeecg.modules.ads.entity.*;
 import org.jeecg.modules.ads.service.*;
+import org.openqa.selenium.json.Json;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.Date;
+
+import static com.bstek.ureport.definition.datasource.DataType.Date;
 
 @Slf4j
 @Service
@@ -39,6 +52,16 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
     private ICtopOauthTokenService tokenService;
     @Autowired
     private IAiKuaishouStrategyMapCreativeService mapCreativeService;
+    @Autowired
+    private IMaterialCutFrameService materialCutFrameService;
+    @Autowired
+    private IMaterialImageInfoService materialImageInfoService;
+
+    @Autowired
+    private IKuaiShouImageGetService imageGetService;
+
+
+    private IKuaiShouMaterialUploadService materialUploadService;
     /**
      *
      * @param strategy
@@ -92,13 +115,21 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
         middleService.save(strategyMiddle);
 
         //6、策略定向拆分数据,写入数据库
-        for (AiKuaishouStrategyTargetBase item:getBases) {
-
-        }
+//        for (AiKuaishouStrategyTargetBase item:getBases) {
+//
+//        }
 
-        //5:循环创建计划,组,创意
-        //拼装计划创建 入参 json
+        //7、一个计划,拼装创建计划的入参json
         JSONObject campaignParams = new JSONObject();
+        campaignParams.put("advertiser_id",token.getAccountId());
+        Date campaignDate = new Date();
+        campaignParams.put("campaign_name",strategy.getStrategyName()+ campaignDate.toString());
+        campaignParams.put("type",Integer.parseInt(strategy.getMarketingGoal()));
+        campaignParams.put("day_budget",0L);
+        JSONArray dayBudgetSchedule = new JSONArray();
+        dayBudgetSchedule.add(0L);
+        campaignParams.put("day_budget_schedule",dayBudgetSchedule);
+
         Map<String, Object> campaignCreateResult = kuaishouInterfaceService.campaignCreate(token.getAccessToken(),
                 token.getAccountId(), campaignParams);
         Integer code = (Integer) campaignCreateResult.get("code");
@@ -106,25 +137,219 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
             return;
         }
         Long campaignId = (Long) campaignCreateResult.get("campaignId");
+
+        // 8、根据定向和素材,两层循环 创建组和创意
+        Integer unitCnt = 1;
         for (AiKuaishouStrategyTargetBase item:getBases) {
+            // 策略定向拆分数据,写入数据库
             AiKuaishouStrategyTargetUnion targetUnion = new AiKuaishouStrategyTargetUnion();
             targetUnion.setStrategyMiddleId(strategyMiddle.getId());
             targetUnion.setStrategyTargetId(item.getId());
             targetUnion.setActualTargetContent(item.getTargetContent());
             targetUnionService.save(targetUnion);
 
+
+            // 拼装创建组的入参 json
+            JSONObject unitParams = new JSONObject();
+            unitParams.put("advertiser_id",token.getAccountId());
+            unitParams.put("campaign_id",campaignId);
+            Date unitDate = new Date();
+            unitParams.put("unit_name", strategy.getStrategyName() +
+                                        item.getTargetType() +
+                                        item.getTargetContent() +
+                                        unitDate.toString() +
+                                        (unitCnt++).toString());
+
+            //TODO 模板里的内容与测试方向冲突?
+            unitParams.put("template_id",strategy.getTemplateId());
+            unitParams.put("bid_type",10);
+
+            //TODO 前端添加对应设置项
+            unitParams.put("use_app_market","?");
+            unitParams.put("app_store","?");
+
+            // 非 OCPM 出价方式,是手动通过AD后台,走通几个成功下载APP的案例
+            // 在本策略中,都是 OCPM 的出价方式
+//            unitParams.put("bid","");
+            unitParams.put("cpa_bid",strategy.getCpaBid());
+//            unitParams.put("smart_bid","");  //当 speed 等于 3 时可用
+            unitParams.put("ocpx_action_type",strategy.getOcpxActionType());
+            unitParams.put("deep_conversion_typ",strategy.getDeepConversionType());
+//            unitParams.put("roi_ratio",""); 付费ROI系数 优化目标为「首日ROI」时必填
+            unitParams.put("deep_conversion_bid",strategy.getDeepConversionBid());
+            unitParams.put("scene_id",JSONArray.parseArray(strategy.getSceneId()));
+            unitParams.put("unit_type",4);
+
+            Date putDate = new Date();
+            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+            String putDateString = formatter.format(putDate);
+            unitParams.put("begin_time",putDateString); // 格式为yyyy-MM-dd,需大于等于当前时间
+//            unitParams.put("end_time",""); 不传值表示从今天开始长期投放
+//            unitParams.put("schedule_time","");
+//            unitParams.put("day_budget","");
+//            unitParams.put("day_budget_schedule","");
+            unitParams.put("convert_id",strategy.getConvertId()); // ?
+//            unitParams.put("url_type",""); 当计划类型为3(获取电商下单)时必填
+            unitParams.put("url_type",strategy.getUrlType()); // 当计划类型为3(获取电商下单)
+//            unitParams.put("web_uri_type",""); // 当计划类型为5(收集销售线索)&使用建站时必填:需使用魔力建站
+            unitParams.put("url",strategy.getUrl()); // 当计划类型是3/4/5时必填
+            unitParams.put("schema_uri",""); // 可选
+            unitParams.put("app_id",""); // long 当计划类型为2时必填,可通过应用列表接口获取应用ID  但是前端为app_ids,是集合?
+            unitParams.put("show_mode",2);
+            unitParams.put("speed",1); // 前端没有设置,暂时默认为加速投放
+//            unitParams.put("site_type",""); // 预约广告,1:IOS预约 缺省为不传或传0
+//            unitParams.put("gift_data",""); // 游戏礼包码 "gift_data": {},仅支持计划类型为 2
+//            unitParams.put("video_landing_page","");
+//            unitParams.put("auto_target","");   智能定向
+//            unitParams.put("smart_cover","");   是否开启智能抽帧
+//            unitParams.put("asset_mining","");  是否开启历史素材挖掘
+
+            // 设置定向内容
+            JSONObject targetJsonObject = new JSONObject();
+            if (strategyTemplate.getTestDirection().equals("region"))
+                targetJsonObject.put("region",item.getTargetContent());
+            else
+                targetJsonObject.put("region",JSONArray.parseArray(strategy.getRegion()));
+
+//            targetJsonObject.put("district_ids",""); 商圈定向 与region字段不能同时传
+//            targetJsonObject.put("user_type",""); 用户类型
+//            targetJsonObject.put("age","");
+
+            if (strategyTemplate.getTestDirection().equals("age"))
+                targetJsonObject.put("ages_range",item.getTargetContent());
+            else
+                targetJsonObject.put("ages_range",JSONArray.parseArray(strategy.getAgesRange()));
+
+            if (strategyTemplate.getTestDirection().equals("gender"))
+                targetJsonObject.put("gender",item.getTargetContent());
+            else
+                targetJsonObject.put("gender",strategy.getGender());
+
+            if (strategyTemplate.getTestDirection().equals("operation_system"))
+                targetJsonObject.put("platform_os",item.getTargetContent());
+            else
+                targetJsonObject.put("platform_os",strategy.getPlatformOs());
+//            targetJsonObject.put("android_osv","");
+//            targetJsonObject.put("ios_osv","");
+//            targetJsonObject.put("network","");
+//            targetJsonObject.put("device_brand","");
+//            targetJsonObject.put("device_price","");
+//            targetJsonObject.put("business_interest_type","");
+//            targetJsonObject.put("business_interest","");
+//            targetJsonObject.put("fans_star","");
+//            targetJsonObject.put("interest_video","");
+//            targetJsonObject.put("app_interest","");
+//            targetJsonObject.put("app_ids",""); // APP行为-按APP名称
+//            targetJsonObject.put("filter_converted_level","");
+            targetJsonObject.put("population",JSONArray.parseArray(strategy.getPopulation()));
+//            targetJsonObject.put("exclude_population","");
+//            targetJsonObject.put("paid_audience","");
+//            targetJsonObject.put("intelli_extend","");
+//            targetJsonObject.put("behavior_interest","");
+            unitParams.put("target",targetJsonObject);
+
+
+            Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(),
+                    token.getAccountId(), unitParams,1);
+            Integer unitCode = (Integer) unitCreateResult.get("code");
+            if(unitCode != 0 ){
+                return;
+            }
+            Long unitId = (Long) unitCreateResult.get("unitId");
+
+            // 选择素材,创建创意
             for(KuaiShouVideoGet videoItem: videoGets){
-                JSONObject unitParams = new JSONObject();
-                Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(),
-                        token.getAccountId(), unitParams,1);
-                Integer unitCode = (Integer) unitCreateResult.get("code");
-                if(unitCode != 0 ){
-                    return;
-                }
-                Long unitId = (Long) unitCreateResult.get("unitId");
+                // 素材自带的封面 ctop_material_image_info 内部素材的自带封面,素造的没有
+                // 素材的智能抽帧封面 ctop_material_cut_frame 其中素造的为8张封面,内部的为15张封面
+                List<MaterialCutFrame> cutFrameList =
+                        materialCutFrameService.getListByVideoSignature(videoItem.getSignature());
+
+                List<MaterialImageInfo> orgFrameList =
+                        materialImageInfoService.getListByVideoSignature(videoItem.getSignature());
+
+
+                JSONArray sceneIdJsonArray = JSONArray.parseArray(strategy.getSceneId());
 
 
                 JSONObject creativeParams = new JSONObject();
+                Integer creativeCnt = 1;
+                if (sceneIdJsonArray.contains(6)&& sceneIdJsonArray.size() == 1){
+                    // 如果广告位只包含 上下滑大屏广告(6),则一个素材搭配1张封面,生成1个创意
+                    if (cutFrameList.size() == 0 && orgFrameList.size()==0){
+                        return;
+                    }
+                    if (orgFrameList.size()!=0){
+                        String imageCode = orgFrameList.get(0).getCode();
+                        String imageUrl = orgFrameList.get(0).getUrl();
+                        KuaiShouImageGet imageGet = imageGetService.getOneByParams(imageUrl);
+                        if ((null == imageGet) || ("".equals(imageGet.getImageToken()))){
+                            // 如果取不到image_token 则调用上传url的方法kuauiShouImageUpload(url, signature, accountId, oauthToken.getAccessToken());
+                            String imageToken = materialUploadService.kuauiShouImageUpload(imageUrl,imageCode,
+                                    token.getAccountId(),token.getAccessToken());
+                            if (null == imageToken){
+                                return;
+                            }
+                        }
+                    }
+                    else{
+                        String imageCode = cutFrameList.get(0).getSignature();
+                        String imageUrl = cutFrameList.get(0).getUrl();
+                        KuaiShouImageGet imageGet = imageGetService.getOneByParams(imageUrl);
+                        if ((null == imageGet) || ("".equals(imageGet.getImageToken()))){
+                            // 如果取不到image_token 则调用上传url的方法kuauiShouImageUpload(url, signature, accountId, oauthToken.getAccessToken());
+                            String imageToken = materialUploadService.kuauiShouImageUpload(imageUrl,imageCode,
+                                    token.getAccountId(),token.getAccessToken());
+                            if (null == imageToken){
+                                return;
+                            }
+                        }
+
+                    }
+                }
+                else
+                {
+                    // 其他情况下,一个素材搭配15张封面,生成15个创意
+                    if (cutFrameList.size() == 0 && orgFrameList.size()==0){
+                        return;
+                    }
+
+                    if (orgFrameList.size() !=0) {
+                        for (int i = 0; i < orgFrameList.size(); i++) {
+                            String imageCode = orgFrameList.get(i).getCode();
+                            String imageUrl = orgFrameList.get(i).getUrl();
+                            creativeCnt++;
+                            if (creativeCnt > 15) {
+                                break;
+                            }
+                        }
+                    }
+
+                    if ((cutFrameList.size() !=0) && (creativeCnt<=15)){
+                        for (int i = 0; i < cutFrameList.size(); i++) {
+                            String imageCode = cutFrameList.get(i).getSignature();
+                            String imageUrl = cutFrameList.get(i).getUrl();
+                            creativeCnt ++;
+                            if (creativeCnt > 15) {
+                                break;
+                            }
+                        }
+                    }
+
+                }
+
+
+
+                creativeParams.put("advertiser_id",token.getAccountId());
+                creativeParams.put("unit_id",unitId);
+                creativeParams.put("creative_name","");
+                creativeParams.put("photo_id","");
+                creativeParams.put("image_token","");
+                creativeParams.put("creative_material_type","");
+                creativeParams.put("","");
+                creativeParams.put("","");
+                creativeParams.put("","");
+                creativeParams.put("","");
+                creativeParams.put("","");
                 Map<String, Object> creativeCreateResult = kuaishouInterfaceService.creativeCreate
                         (token.getAccessToken(), token.getAccountId(), creativeParams,1);
                 Integer creativeCode = (Integer) creativeCreateResult.get("code");