Pārlūkot izejas kodu

新素材+跑量素材 混搭逻辑

liyuyi@c-top.com.cn 4 gadi atpakaļ
vecāks
revīzija
90a5e5b69a

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

@@ -9,6 +9,7 @@ import cn.com.ctop.common.module.service.IMaterialImageInfoService;
 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.mapper.KuaiShouVideoGetMapper;
 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;
@@ -56,6 +57,8 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
     private IKuaiShouImageGetService imageGetService;
     @Autowired
     private IKuaiShouMaterialUploadService materialUploadService;
+    @Autowired
+    private KuaiShouVideoGetMapper videoGetMapper;
     /**
      *
      * @param strategy
@@ -69,12 +72,7 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
             log.info("token获取失败=>accountId:{}",strategy.getAccountId());
             return;
         }
-        //1:获取相应账户下的最新的5条素材信息
-        List<KuaiShouVideoGet> videoGets = videoGetService.getNewVideoByAccountId(accountId,1);
-        if(null == videoGets){
-            log.info("素材获取失败=>accountId:{}",accountId);
-            return;
-        }
+
         //策略类型
         String scenes = strategy.getScenes();
         //根据策略类型获取策略模板信息
@@ -83,6 +81,35 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
             log.info("策略模板信息获取失败=>testDirection:{}",scenes);
             return;
         }
+
+        // 1: 根据模板信息表里的 material_select_method (素材选择方式),得到"跑量视频"和"上新视频"获取方式
+        // {'highQualityMaterial':{'days':7, 'num':5},'newMaterialNum':5}
+        // TODO 更新该账户下的 ctop_kuaishou_video_get 数据
+//        videoGetService.
+
+        JSONObject MaterialSelectMethod = JSONObject.parseObject(strategyTemplate.getMaterialSelectMethod());
+        List<KuaiShouVideoGet> newVideos = new ArrayList<KuaiShouVideoGet>();
+        List<KuaiShouVideoGet> highQualityVideos = new ArrayList<KuaiShouVideoGet>();
+
+        if (MaterialSelectMethod.containsKey("newMaterialNum")){
+            int newVideoCnt = (int) MaterialSelectMethod.get("newMaterialNum");
+            newVideos = videoGetService.getNewVideoDescDate(accountId,newVideoCnt);
+        }
+        if(MaterialSelectMethod.containsKey("highQualityMaterial")){
+            int days = MaterialSelectMethod.getJSONObject("highQualityMaterial").getInteger("days");
+            int highQualityVideoCnt = MaterialSelectMethod.getJSONObject("highQualityMaterial").getInteger("num");
+            highQualityVideos = videoGetMapper.getHighQualityVideo(accountId,days,highQualityVideoCnt);
+        }
+
+        // 跑量视频 + 上新视频 合并到一个list, 为单素材搭配组做准备 TODO
+        List<KuaiShouVideoGet> fullVideos = new ArrayList<KuaiShouVideoGet>();
+        fullVideos.addAll(highQualityVideos);
+        fullVideos.addAll(newVideos);
+        if(null == fullVideos){
+            log.info("素材获取失败=>accountId:{}",accountId);
+            return;
+        }
+
         String materialFixType = strategyTemplate.getMaterialFixType();
         Date campaignDate = new Date();
         String timestamp = DateUtils.formatDate(campaignDate,"yyyyMMddHHmmss");
@@ -96,7 +123,7 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
             //7、一个计划,拼装创建计划的入参json
             JSONObject campaignParams = new JSONObject();
             campaignParams.put("advertiser_id",token.getAccountId());
-            String campaignName = "户14-上下滑&信息流" + "-自定义001"+ "剪辑-低价-低价包邮-活动-年龄18岁以上-单出价-"+ timestamp;
+            String campaignName = "户14-上下滑&信息流" + "-自定义001-"+ "剪辑-低价-低价包邮-活动-年龄18岁以上-单出价-"+ timestamp;
             campaignParams.put("campaign_name",campaignName);
             campaignParams.put("type",Integer.parseInt(strategy.getMarketingGoal()));
             campaignParams.put("day_budget",0L);
@@ -109,12 +136,12 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
             }
             Long campaignId = (Long) campaignCreateResult.get("campaignId");
             int unitCnt = 1;
-            // 8、根据定向和素材,两层循环 创建组和创意
+            // 8、根据素材和出价,两层循环 创建组和创意
             for (Long item:getCapbids) {
                 //判定素材搭配方式
                 if(null!=materialFixType&&materialFixType.trim().equals("single")){
                     // 选择素材,创建创意
-                    for(KuaiShouVideoGet videoItem: videoGets){
+                    for(KuaiShouVideoGet videoItem: fullVideos){
                         //拼装广告组参数
                         unitCnt ++;
                         String unitName = campaignName + "-" + unitCnt;
@@ -146,41 +173,97 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
                             createCreativeByImage(cutFrameList,orgFrameList,token,creativeParams,campaignId,unitId,strategy,videoItem,15,null);
                         }
                     }
-                }else{
+                }
+                else{
                     //混搭素材逻辑
-                    String unitName = campaignName + "-" + unitCnt;
-                    JSONObject unitParams = createUnitParams(token, campaignId, strategy, item, unitName);
-                    Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(), token.getAccountId(), unitParams,1);
-                    Integer unitCode = (Integer) unitCreateResult.get("code");
-                    String unitMessage = (String) unitCreateResult.get("message");
-                    if(unitCode != 0 ){
-                        log.info("组创建失败=>accountId:{};message:{}",accountId,unitMessage);
-                        continue;
+                    //跑量素材
+                    if(highQualityVideos.size() > 0){
+                        // 取模和余数:
+                        int mod = highQualityVideos.size() / 15;
+                        int rem = highQualityVideos.size() % 15;
+                        int innerUnitCnt = 0;
+                        if(mod!=0){
+                            for(int i=0;i<mod;i++){
+                                String unitName = campaignName + "-跑量-" + item + "-" + innerUnitCnt;
+                                JSONObject unitParams = createUnitParams(token, campaignId, strategy, item, unitName);
+                                Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(), token.getAccountId(), unitParams,1);
+                                Integer unitCode = (Integer) unitCreateResult.get("code");
+                                String unitMessage = (String) unitCreateResult.get("message");
+                                if(unitCode != 0 ){
+                                    log.info("组创建失败=>accountId:{};message:{}",accountId,unitMessage);
+                                    continue;
+                                }
+                                Long unitId = (Long) unitCreateResult.get("unitId");
+                                for(int j=0;j<15;j++){
+                                    JSONObject creativeParams = creativeParams(token,unitId,highQualityVideos.get(i*15+j),unitCnt,strategy);
+                                    createCreative(token,creativeParams,campaignId,unitId,strategy,null,1,highQualityVideos.get(i*15+j));
+                                }
+                                innerUnitCnt++;
+                            }
+
+                        }
+                        if(rem!=0){
+                            String unitName = campaignName + "-跑量-" + item + "-" + innerUnitCnt;
+                            JSONObject unitParams = createUnitParams(token, campaignId, strategy, item, unitName);
+                            Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(), token.getAccountId(), unitParams,1);
+                            Integer unitCode = (Integer) unitCreateResult.get("code");
+                            String unitMessage = (String) unitCreateResult.get("message");
+                            if(unitCode != 0 ){
+                                log.info("组创建失败=>accountId:{};message:{}",accountId,unitMessage);
+                                continue;
+                            }
+                            Long unitId = (Long) unitCreateResult.get("unitId");
+
+                            for(int j=0;j<rem;j++){
+                                JSONObject creativeParams = creativeParams(token,unitId,highQualityVideos.get(mod*15+j),unitCnt,strategy);
+                                createCreative(token,creativeParams,campaignId,unitId,strategy,null,1,highQualityVideos.get(mod*15+j));
+                            }
+                        }
                     }
-                    Long unitId = (Long) unitCreateResult.get("unitId");
-                    // 选择素材,创建创意
-                    for(KuaiShouVideoGet videoItem: videoGets){
-                        //拼装广告组参数
-                        JSONObject creativeParams = creativeParams(token,unitId,videoItem,unitCnt,strategy);
-                        JSONArray sceneIdJsonArray = JSONArray.parseArray(strategy.getSceneId());
-                        // 如果广告位只包含 上下滑大屏广告(6),则一个素材搭配1张封面,生成1个创意
-                        if (sceneIdJsonArray.contains(6) && sceneIdJsonArray.size() == 1){
-                            //直接创建创意
-                            createCreative(token,creativeParams,campaignId,unitId,strategy,null,1,videoItem);
-                        } else {
-                            // 素材自带的封面 ctop_material_image_info 内部素材的自带封面,素造的没有
-                            // 素材的智能抽帧封面 ctop_material_cut_frame 其中素造的为8张封面,内部的为15张封面
-                            List<MaterialCutFrame> cutFrameList = materialCutFrameService.getListByVideoSignature(videoItem.getSignature());
-                            List<MaterialImageInfo> orgFrameList = materialImageInfoService.getListByVideoSignature(videoItem.getSignature());
-                            // 其他情况下,一个素材搭配15张封面,生成15个创意
-                            if ((null == cutFrameList||cutFrameList.isEmpty())&&(null == orgFrameList|| orgFrameList.isEmpty())){
-                                log.info("未获取到视频封面=>videoSignature:{}",videoItem.getSignature());
+                    // 新上素材混搭
+                    if(newVideos.size() > 0){
+                        // 取模和余数:
+                        int mod = newVideos.size() / 15;
+                        int rem = newVideos.size() % 15;
+                        int innerUnitCnt = 0;
+                        if(mod!=0){
+                            for(int i=0;i<mod;i++){
+                                String unitName = campaignName + "-上新-" + item + "-" + innerUnitCnt;
+                                JSONObject unitParams = createUnitParams(token, campaignId, strategy, item, unitName);
+                                Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(), token.getAccountId(), unitParams,1);
+                                Integer unitCode = (Integer) unitCreateResult.get("code");
+                                String unitMessage = (String) unitCreateResult.get("message");
+                                if(unitCode != 0 ){
+                                    log.info("组创建失败=>accountId:{};message:{}",accountId,unitMessage);
+                                    continue;
+                                }
+                                Long unitId = (Long) unitCreateResult.get("unitId");
+                                for(int j=0;j<15;j++){
+                                    JSONObject creativeParams = creativeParams(token,unitId,newVideos.get(i*15+j),unitCnt,strategy);
+                                    createCreative(token,creativeParams,campaignId,unitId,strategy,null,1,newVideos.get(i*15+j));
+                                }
+                                innerUnitCnt++;
+                            }
+
+                        }
+                        if(rem!=0){
+                            String unitName = campaignName + "-上新-" + item + "-" + innerUnitCnt;
+                            JSONObject unitParams = createUnitParams(token, campaignId, strategy, item, unitName);
+                            Map<String, Object> unitCreateResult = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(), token.getAccountId(), unitParams,1);
+                            Integer unitCode = (Integer) unitCreateResult.get("code");
+                            String unitMessage = (String) unitCreateResult.get("message");
+                            if(unitCode != 0 ){
+                                log.info("组创建失败=>accountId:{};message:{}",accountId,unitMessage);
                                 continue;
                             }
-                            createCreativeByImage(cutFrameList,orgFrameList,token,creativeParams,campaignId,unitId,strategy,videoItem,1,null);
+                            Long unitId = (Long) unitCreateResult.get("unitId");
+
+                            for(int j=0;j<rem;j++){
+                                JSONObject creativeParams = creativeParams(token,unitId,newVideos.get(mod*15+j),unitCnt,strategy);
+                                createCreative(token,creativeParams,campaignId,unitId,strategy,null,1,newVideos.get(mod*15+j));
+                            }
                         }
                     }
-                    unitCnt ++;
                 }
             }
         }else if(scenes.equals(2)){
@@ -225,7 +308,7 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
                     AiKuaishouStrategyTargetUnion targetUnion = new AiKuaishouStrategyTargetUnion(strategyMiddle.getId(),item.getId(),item.getTargetContent());
                     targetUnionService.save(targetUnion);
                     // 选择素材,创建创意
-                    for(KuaiShouVideoGet videoItem: videoGets){
+                    for(KuaiShouVideoGet videoItem: fullVideos){
                         //拼装广告组参数
                         unitCnt++;
                         String unitName = campaignName + "-" + unitCnt;
@@ -262,7 +345,7 @@ public class AiStrategyServiceImpl implements IAiStrategyService {
                     AiKuaishouStrategyTargetUnion targetUnion = new AiKuaishouStrategyTargetUnion(strategyMiddle.getId(),item.getId(),item.getTargetContent());
                     targetUnionService.save(targetUnion);
                     // 选择素材,创建创意
-                    for(KuaiShouVideoGet videoItem: videoGets){
+                    for(KuaiShouVideoGet videoItem: fullVideos){
                         unitCnt++;
                         String unitName = campaignName + "-" + unitCnt;
                         JSONObject unitParams = createUnitParams(token,campaignId,strategy,strategyTemplate, item,timestamp,unitName);

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

@@ -19,4 +19,9 @@ public interface KuaiShouVideoGetMapper extends BaseMapper<KuaiShouVideoGet> {
     void replaceBatch(@Param(value = "videos") List<KuaiShouVideoGet> videoGets);
 
     List<KuaiShouVideoGetVo> getVideoList(Map<String, Object> requestMap);
+
+    List<KuaiShouVideoGet> getHighQualityVideo(long accountId,int days,int num);
+
+
+
 }

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

@@ -59,4 +59,28 @@
 
 
 
+    <select id="getHighQualityVideo" parameterType="java.util.Map"
+            resultType="cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet">
+        select * from ctop_kuaishou_video_get
+        where account_id = #{accountId}
+        and signature in
+        (
+        select
+        material.signature
+        from
+        ctop_kuaishou_report_daily_material daily_material
+        inner join
+        ctop_user_allocation allocation
+        on daily_material.account_id = allocation.account_id
+        where  allocation.project_id in (select project_id from ctop_user_allocation where account_id = #{accountId})
+        and  to_days(now()) - to_days(daily_material.stat_date) &lt;= #{days}
+        and daily_material.signature is not null
+        GROUP BY daily_material.signature
+        order by sum(daily_material.charge) desc
+        limit #{num}
+        )
+    </select>
+
+
+
 </mapper>

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

@@ -2,6 +2,7 @@ package cn.com.ctop.kuaishou.modules.batch.service;
 
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
 import cn.com.ctop.kuaishou.modules.batch.entity.vo.KuaiShouVideoGetVo;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouVideoGetMapper;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 import java.util.List;
@@ -13,6 +14,9 @@ import java.util.Map;
  * @Date: 2019-07-25
  * @Version: V1.0
  */
+
+
+
 public interface IKuaiShouVideoGetService extends IService<KuaiShouVideoGet> {
     void replaceBatch(List<KuaiShouVideoGet> videoGets);
 
@@ -21,4 +25,11 @@ public interface IKuaiShouVideoGetService extends IService<KuaiShouVideoGet> {
     List<KuaiShouVideoGetVo> getVideoList(Map<String, Object> stringObjectMap);
 
     List<KuaiShouVideoGet> getNewVideoByAccountId(Long accountId,Integer videoAiStatus);
+
+
+    List<KuaiShouVideoGet> getNewVideoDescDate(Long accountId,Integer newVideoCnt);
+
+
+
+
 }

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

@@ -133,4 +133,19 @@ public class KuaiShouVideoGetServiceImpl extends ServiceImpl<KuaiShouVideoGetMap
         queryWrapper.orderByDesc("stat_date");
         return this.list(queryWrapper);
     }
+
+
+    @Override
+    public List<KuaiShouVideoGet>getNewVideoDescDate(Long accountId,Integer newVideoCnt){
+        QueryWrapper<KuaiShouVideoGet>queryWrapper = new QueryWrapper<>();
+        if(null!=accountId&&accountId!=0){
+            queryWrapper.eq("account_id",accountId);
+        }
+        if(null!=newVideoCnt && newVideoCnt>0){
+            queryWrapper.orderByDesc("stat_date");
+            queryWrapper.last("limit ${newVideoCnt}");
+        }
+        return this.list(queryWrapper);
+    }
+
 }