Ver Fonte

Merge remote-tracking branch 'origin/master'

yumeng há 2 anos atrás
pai
commit
0d071a6b91
19 ficheiros alterados com 569 adições e 102 exclusões
  1. 4 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/common/module/utils/KuaishouInterfaceConstant.java
  2. 59 4
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/BatchController.java
  3. 14 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaiShouBatchGroupTemplate.java
  4. 14 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouBatchGroupPreview.java
  5. 4 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouTemplateTarget.java
  6. 5 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaishouPopulationMapper.java
  7. 32 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouPopulationMapper.xml
  8. 1 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouTemplateMapper.xml
  9. 2 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouTemplateTargetMapper.xml
  10. 11 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouInterfaceService.java
  11. 4 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouPopulationService.java
  12. 12 8
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouGroupTemplateServiceImpl.java
  13. 83 26
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouBatchCampaignPreviewServiceImpl.java
  14. 171 28
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouBatchCreativePreviewServiceImpl.java
  15. 131 30
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouInterfaceServiceImpl.java
  16. 10 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouPopulationServiceImpl.java
  17. 3 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouTemplateServiceImpl.java
  18. 1 0
      jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/clean/service/impl/TrackMonitorConfigureServiceImpl.java
  19. 8 6
      jeecg-boot-module-system/src/main/java/cn/com/ctop/reimburse/mondule/entity/ReimburseProject.java

+ 4 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/common/module/utils/KuaishouInterfaceConstant.java

@@ -158,6 +158,10 @@ public class KuaishouInterfaceConstant {
      * 获取人群包接口
      */
     public static final String POPULATION_LIST = "/rest/openapi/v2/dmp/population/list";
+    /**
+     * 获取联盟定向媒体包列表
+     */
+    public static final String MEDIA_LIST = "/rest/openapi/v1/asset/media/list";
 
     /**
      * 删除人群包接口

+ 59 - 4
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/controller/BatchController.java

@@ -9,13 +9,42 @@ import cn.com.ctop.common.module.service.IUserAllocationService;
 import cn.com.ctop.common.module.utils.BigDecimalUtil;
 import cn.com.ctop.common.module.utils.Check;
 import cn.com.ctop.common.module.utils.RandomUtil;
-import cn.com.ctop.kuaishou.modules.batch.entity.*;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouActionBarText;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouAdvertiserBaseInfo;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouAppInfo;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouAppList;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCampaign;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCreative;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouDirectionalTemplate;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroupTarget;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouRegionListParent;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouTargetingTags;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouPopulation;
 import cn.com.ctop.kuaishou.modules.batch.entity.vo.ConvertVo;
 import cn.com.ctop.kuaishou.modules.batch.entity.vo.SpendVo;
 import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouCampaignMapper;
 import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouGroupMapper;
 import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouTargetingTagsMapper;
-import cn.com.ctop.kuaishou.modules.batch.service.*;
+import cn.com.ctop.kuaishou.modules.batch.service.IBatchService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouActionBarTextService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouAdvertiserBaseInfoService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouAppInfoService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouAppListService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCampaignService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCreativeService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouDirectionalTemplateService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupTargetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouRegionListParentService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouPopulationService;
+import cn.com.ctop.kuaishou.modules.batch.service.ISyncPullMaterialService;
 import cn.com.ctop.kuaishou.modules.report.service.IEtlKuaiShouGroupDailyReportService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -28,7 +57,14 @@ import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
@@ -138,7 +174,6 @@ public class BatchController {
             };
             thread1.start();
 
-
             Thread thread2 = new Thread() {
                 @Override
                 public void run() {
@@ -156,6 +191,14 @@ public class BatchController {
                 }
             };
             thread4.start();
+
+            Thread thread5 = new Thread() {
+                @Override
+                public void run() {
+                    iKuaishouInterfaceService.getMediaList(accountId, oauthToken.getAccessToken(), 1);
+                }
+            };
+            thread5.start();
         } catch (Exception e) {
             e.printStackTrace();
             result.setSuccess(false);
@@ -165,6 +208,18 @@ public class BatchController {
         return result;
     }
 
+    /**
+     * 获取联盟定向媒体包列表
+     */
+    @GetMapping(value = "/getMedias")
+    public Result<Object> getMedias(Long accountId) {
+        try {
+            return Result.ok(iKuaishouInterfaceService.getMedias(accountId));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
 
     /**
      * 获取广告计划列表

+ 14 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaiShouBatchGroupTemplate.java

@@ -154,6 +154,20 @@ public class KuaiShouBatchGroupTemplate {
     @Excel(name = "1:固定出价 2:随机出价 值为1时取bid或cpa_bid  2 区 bid_max  bid_min", width = 15)
     @ApiModelProperty(value = "1:固定出价 2:随机出价 值为1时取bid或cpa_bid  2 区 bid_max  bid_min")
     private Integer templateBidType;
+
+    /**
+     * 媒体定向包
+     */
+    @Excel(name = "媒体定向包", width = 15)
+    @ApiModelProperty(value = "媒体定向包")
+    private String media;
+
+    /**
+     * 付费人群包
+     */
+    @Excel(name = "媒体定向排除包", width = 15)
+    @ApiModelProperty(value = "媒体定向排除包")
+    private String excludeMedia;
     /**
      * 创建时间
      */

+ 14 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouBatchGroupPreview.java

@@ -207,6 +207,20 @@ public class KuaishouBatchGroupPreview {
     @Excel(name = "应用列表", width = 15)
     @ApiModelProperty(value = "应用列表")
     private String appStore;
+
+    /**
+     * 媒体定向包
+     */
+    @Excel(name = "媒体定向包", width = 15)
+    @ApiModelProperty(value = "媒体定向包")
+    private String media;
+
+    /**
+     * 付费人群包
+     */
+    @Excel(name = "媒体定向排除包", width = 15)
+    @ApiModelProperty(value = "媒体定向排除包")
+    private String excludeMedia;
     /**
      * 创建时间
      */

+ 4 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/entity/KuaishouTemplateTarget.java

@@ -72,6 +72,10 @@ public class KuaishouTemplateTarget {
     @ApiModelProperty(value = "年龄最大值")
     private Integer max;
     /**
+     * 已安装用户  0:过滤(默认),1:不限
+     */
+    private Integer disableInstalledAppSwitch;
+    /**
      * 性别 1:女性, 2:男性,0 表示不限
      */
     @Excel(name = "性别 1:女性, 2:男性,0 表示不限", width = 15)

+ 5 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/KuaishouPopulationMapper.java

@@ -1,6 +1,7 @@
 package cn.com.ctop.kuaishou.modules.batch.mapper;
 
 import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouPopulation;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -18,4 +19,8 @@ public interface KuaishouPopulationMapper extends BaseMapper<KuaishouPopulation>
     void replaceBatch(@Param("addList") List<KuaishouPopulation> addList);
 
     void deleteByAccountId(@Param("accountId") Long accountId);
+
+    void replaceBatchMedia(@Param("list") List<JSONObject> list);
+
+    List<JSONObject> getMedias(@Param("accountId")Long accountId);
 }

+ 32 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouPopulationMapper.xml

@@ -33,9 +33,41 @@
         </foreach>
     </insert>
 
+    <insert id="replaceBatchMedia">
+        replace into ctop_kuaishou_media(
+        account_id,
+        media_id,
+        media_name,
+        source_type,
+        pos_ids
+        )
+        values
+        <foreach collection="list" item="media" separator=",">
+            (
+            #{media.accountId},
+            #{media.mediaId},
+            #{media.name},
+            #{media.sourceType},
+            #{media.posIds}
+            )
+        </foreach>
+    </insert>
+
     <delete id="deleteByAccountId">
         delete
         from ctop_kuaishou_population
         where account_id = #{accountId}
     </delete>
+
+    <select id="getMedias" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT  account_id as 'accountId',
+                media_id as 'mediaId',
+                media_name as 'mediaName',
+                source_type as 'sourceType',
+                pos_ids as 'posIds'
+        FROM ctop_kuaishou_media
+        WHERE account_id = #{accountId}
+        ORDER BY update_time DESC
+    </select>
+
 </mapper>

+ 1 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouTemplateMapper.xml

@@ -46,6 +46,7 @@
         <if test="autoTarget != null and autoTarget != '' ">
             AND t1.auto_target = #{autoTarget}
         </if>
+        order by t1.update_time desc
     </select>
 
 

+ 2 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/mapper/xml/KuaishouTemplateTargetMapper.xml

@@ -13,6 +13,7 @@
         min,
         max,
         gender,
+        disable_installed_app_switch,
         platform_os,
         android_osv,
         ios_osv,
@@ -53,6 +54,7 @@
             #{templateTarget.min},
             #{templateTarget.max},
             #{templateTarget.gender},
+            #{templateTarget.disableInstalledAppSwitch},
             #{templateTarget.platformOs},
             #{templateTarget.androidOsv},
             #{templateTarget.iosOsv},

+ 11 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouInterfaceService.java

@@ -424,6 +424,15 @@ public interface IKuaishouInterfaceService {
      */
     void getPopulationList(Long accountId, String accessToken, Integer page);
 
+     /**
+     * 获取人群包接口
+     *
+     * @param accountId
+     * @param accessToken
+     * @return
+     */
+    void getMediaList(Long accountId, String accessToken, Integer page);
+
 
     /**
      * 获取定向标签
@@ -506,6 +515,8 @@ public interface IKuaishouInterfaceService {
      * @return
      */
     JSONObject mcbConversionInfos(Long accountId, String accessToken, Integer sceneCategory, Integer campaignType, JSONArray sceneIds, Long appId);
+
+    List<JSONObject> getMedias(Long accountId);
 }
 
 

+ 4 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/IKuaishouPopulationService.java

@@ -106,4 +106,8 @@ public interface IKuaishouPopulationService extends IService<KuaishouPopulation>
     Long predictionPopulation(Long accountId, JSONObject obj, String accessToken);
 
     void replaceBatch(List<KuaishouPopulation> addList);
+
+    void replaceBatchMedia(List<JSONObject> list);
+
+    List<JSONObject> getMedias(Long accountId);
 }

+ 12 - 8
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouGroupTemplateServiceImpl.java

@@ -577,20 +577,24 @@ public class KuaiShouGroupTemplateServiceImpl extends ServiceImpl<KuaiShouGroupT
             target.put("app_interest", JSONArray.parseArray(templateTarget.getAppInterest()));
         }
 
-        if (!Check.isNull(templateTarget.getAppIds())) {
-            target.put("app_ids", JSONArray.parseArray(templateTarget.getAppIds()));
+        JSONArray appIds = JSONArray.parseArray(templateTarget.getAppIds());
+        if (!Check.isNull(appIds) && !appIds.isEmpty()) {
+            target.put("app_ids", appIds);
         }
 
-        if (!Check.isNull(templateTarget.getPopulation())) {
-            target.put("population", JSONArray.parseArray(templateTarget.getPopulation()));
+        JSONArray population = JSONArray.parseArray(templateTarget.getPopulation());
+        if (!Check.isNull(population) && !population.isEmpty()) {
+            target.put("population", population);
         }
 
-        if (!Check.isNull(templateTarget.getExcludePopulation())) {
-            target.put("exclude_population", JSONArray.parseArray(templateTarget.getExcludePopulation()));
+        JSONArray excludePopulation = JSONArray.parseArray(templateTarget.getExcludePopulation());
+        if (!Check.isNull(excludePopulation) && !excludePopulation.isEmpty()) {
+            target.put("exclude_population", excludePopulation);
         }
 
-        if (!Check.isNull(templateTarget.getPaidAudience())) {
-            target.put("paid_audience", JSONArray.parseArray(templateTarget.getPaidAudience()));
+        JSONArray paidAudience = JSONArray.parseArray(templateTarget.getPaidAudience());
+        if (!Check.isNull(paidAudience) && !paidAudience.isEmpty()) {
+            target.put("paid_audience", paidAudience);
         }
         //-------------兴趣行为定向
     /*    JSONObject behaviorInterest = new JSONObject();

+ 83 - 26
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouBatchCampaignPreviewServiceImpl.java

@@ -20,6 +20,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.xxl.job.core.enums.NoEn;
 import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,6 +31,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Random;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -368,33 +370,74 @@ public class KuaishouBatchCampaignPreviewServiceImpl extends ServiceImpl<Kuaisho
                     groupPreviewMapper.insert(groupPreview);
                     JSONObject material = materialList.getJSONObject(j);
                     JSONArray photoArr = material.getJSONArray("photoArr");
-                    if (matchingMethod == 2) {
-                        //创意匹配
-                        descriptionList = advertisingSlogan(descriptionList, photoArr);
-                    }
-                    for (int k = 0; k < photoArr.size(); k++) {
-                        creativePreview.setId(null);
-                        creativePreview.setSiteId(siteId);
-                        creativePreview.setClickTrackUrl(clickTrackUrl);
-                        creativePreview.setActionbarClickUrl(actionbarClickUrl);
-                        JSONObject photo = photoArr.getJSONObject(k);
-                        JSONObject image = photo.getJSONObject("image");
-                        creativePreview.setPlanId(campaignPreview.getId());
-                        creativePreview.setGroupId(groupPreview.getId());
-                        creativePreview.setPhotoId(photo.getString("photoId"));
-                        creativePreview.setCreativeName(photo.getString("creativeName") + k);
-                        creativePreview.setImageTokens(photo.getString("imageToken"));
-                        creativePreview.setMaterialType(photo.getString("materialType"));
-                        creativePreview.setImageUrl(image.getString("url"));
-                        creativePreview.setImageSignature(image.getString("signature"));
-                        if (matchingMethod == 1) {
-                            creativePreview.setDescription(photo.getString("description"));
-                        } else if (matchingMethod == 2) {
-                            creativePreview.setDescription(descriptionList.getString(k));
-                        } else if (matchingMethod == 3) {
-                            creativePreview.setDescription(descriptionList.getString(j));
+                    if (groupPreview.getUnitType() == 4) {
+                        if (matchingMethod == 2) {
+                            //创意匹配
+                            descriptionList = advertisingSlogan(descriptionList, photoArr);
+                        }
+                        for (int k = 0; k < photoArr.size(); k++) {
+                            creativePreview.setId(null);
+                            creativePreview.setSiteId(siteId);
+                            creativePreview.setClickTrackUrl(clickTrackUrl);
+                            creativePreview.setActionbarClickUrl(actionbarClickUrl);
+                            JSONObject photo = photoArr.getJSONObject(k);
+                            JSONObject image = photo.getJSONObject("image");
+                            creativePreview.setPlanId(campaignPreview.getId());
+                            creativePreview.setGroupId(groupPreview.getId());
+                            creativePreview.setPhotoId(photo.getString("photoId"));
+                            creativePreview.setCreativeName(photo.getString("creativeName") + k);
+                            creativePreview.setImageTokens(photo.getString("imageToken"));
+                            creativePreview.setMaterialType(photo.getString("materialType"));
+                            if (matchingMethod == 1) {
+                                creativePreview.setDescription(photo.getString("description"));
+                            } else if (matchingMethod == 2) {
+                                creativePreview.setDescription(descriptionList.getString(k));
+                            } else if (matchingMethod == 3) {
+                                creativePreview.setDescription(descriptionList.getString(j));
+                            }
+                            creativePreviewMapper.insert(creativePreview);
+                        }
+                    } else {
+                        if (photoArr.size() >= 3) {
+                            List<JSONObject> photoIds = JSONArray.parseArray(photoArr.toJSONString(), JSONObject.class);
+                            List<List<JSONObject>> splitPhotoIds = Lists.newArrayList(Lists.partition(photoIds, 10));
+                            for (int k = 0; k < splitPhotoIds.size(); k++) {
+                                //广告语
+                                JSONArray descriptions = materialArray.getJSONArray("descriptionList");
+                                if (descriptions.size() > 3) {
+                                    creativePreview.setDescription(getRandomFromList(descriptions));
+                                } else {
+                                    creativePreview.setDescription(JSONArray.toJSONString(descriptions));
+                                }
+
+                                //photoId集合
+                                List<String> photos = new ArrayList<>();
+                                // 图片集合
+                                List<String> images = new ArrayList<>();
+                                for (JSONObject object : splitPhotoIds.get(k)) {
+                                    if (!Check.isNull(object.getString("photoId"))) {
+                                        photos.add(object.getString("photoId"));
+                                    }
+                                    if (!Check.isNull(object.getString("imageToken"))) {
+                                        images.add(object.getString("imageToken"));
+                                    }
+                                }
+                                creativePreview.setId(null);
+                                creativePreview.setSiteId(siteId);
+                                creativePreview.setClickTrackUrl(clickTrackUrl);
+                                creativePreview.setActionbarClickUrl(actionbarClickUrl);
+                                creativePreview.setPlanId(campaignPreview.getId());
+                                creativePreview.setGroupId(groupPreview.getId());
+                                if (!photos.isEmpty()) {
+                                    creativePreview.setPhotoId(JSONArray.toJSONString(photos));
+                                }
+                                if (!images.isEmpty()) {
+                                    creativePreview.setImageTokens(JSONArray.toJSONString(images));
+                                }
+                                creativePreview.setCreativeName("程序化组-" + k);
+                                creativePreviewMapper.insert(creativePreview);
+                            }
                         }
-                        creativePreviewMapper.insert(creativePreview);
                     }
                 }
             }
@@ -503,6 +546,20 @@ public class KuaishouBatchCampaignPreviewServiceImpl extends ServiceImpl<Kuaisho
 
     }
 
+    //从集合里随机获取不重复的3个值
+    private String getRandomFromList(JSONArray arr) {
+        List<String> ids = JSONArray.parseArray(arr.toJSONString(), String.class);
+        Random r = new Random();
+        List<String> ret = new ArrayList<>();
+        int index = 0;
+        for (int i = 0; i < 3; i++) {
+            index = r.nextInt(ids.size() - i);
+            ret.add(ids.get(index));
+            ids.remove(index);
+        }
+        return JSONArray.toJSONString(ret);
+    }
+
     /**
      * 判断非空
      *

+ 171 - 28
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouBatchCreativePreviewServiceImpl.java

@@ -5,6 +5,10 @@ import cn.com.ctop.common.module.entity.MaterialCutFrame;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
 import cn.com.ctop.common.module.service.IMaterialCutFrameService;
 import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
+import cn.com.ctop.common.module.utils.PropertiesUtils;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouLandpagePackageService;
 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.KuaishouBatchCampaignPreview;
@@ -20,6 +24,7 @@ import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouBatchCreativePreviewService;
 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.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -31,6 +36,7 @@ import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
@@ -184,7 +190,7 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
             updateStatus.setMessage("执行成功");
         }
         campaignPreviewMapper.updateById(updateStatus);
-        if (campaign.getPutStatus() == 2) {
+        if (campaign.getPutStatus() == 2 && !Check.isNull(updateStatus.getCampaignId())) {
             kuaiShouUpdateService.updateCampaignStatus(oauthToken.getAccessToken(), oauthToken.getAccountId(), updateStatus.getCampaignId(), campaign.getPutStatus(), "timingStart");
         }
         //创意广告组
@@ -292,6 +298,14 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
                     Integer code = unionJson.getInteger("code");
                     if (code == 0) {
                         JSONObject target = unionJson.getJSONObject("target");
+                        JSONArray media = JSONObject.parseArray(groupPreview.getMedia());
+                        if (!Check.isNull(media) && !media.isEmpty()) {
+                            target.put("media", media);
+                        }
+                        JSONArray excludeMedia = JSONObject.parseArray(groupPreview.getExcludeMedia());
+                        if (!Check.isNull(excludeMedia) && !excludeMedia.isEmpty()) {
+                            target.put("exclude_media", excludeMedia);
+                        }
                         unitJson.put("target", target);
                     }
                 }
@@ -342,7 +356,11 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
                     updateStatus.setIsSuccess(1);
                     updateStatus.setMessage((String) returnUnitMap.get("message"));
                     updateStatus.setUnitId(unitId);
-                    createCopyCreatives(token, groupPreview.getKuaishouBatchCreativePreviews(), unitId, campaignId);
+                    if (groupPreview.getUnitType() == 4) {
+                        createCopyCreatives(token, groupPreview.getKuaishouBatchCreativePreviews(), unitId, campaignId);
+                    } else {
+                        createCopyProgramCreatives(token, groupPreview.getKuaishouBatchCreativePreviews(), unitId, campaignId);
+                    }
                 } else {
                     updateStatus.setIsSuccess(0);
                     updateStatus.setMessage((String) returnUnitMap.get("message"));
@@ -379,10 +397,6 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
 
     /**
      * 根据预览数据创建广告创意
-     *
-     * @param oauthToken
-     * @param unit_id
-     * @param creative_list
      */
     private void createCreative(CtopOauthToken oauthToken, Long campaignId, Long unitId, KuaishouBatchCreativePreview creativePreview) throws Exception {
         KuaishouBatchCreativePreview updateStatus = new KuaishouBatchCreativePreview();
@@ -397,24 +411,17 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
             if (!Check.isNull(creativePreview.getPhotoId())) {
                 createJson.put("photo_id", creativePreview.getPhotoId());  // 视频ID
                 KuaiShouVideoGet video = videoGetService.getVideoByPhotoId(Long.valueOf(creativePreview.getPhotoId()));
-                if (!Check.isNull(video)) {
-                    createJson.put("creative_material_type", video.getMaterialType());  // 素材类型
+                if (Check.isNull(video)) {
+                    log.info("账户:{},photoId:{} 没有查询到视频,素材类型指定为竖版视频", oauthToken.getAccountId(), creativePreview.getPhotoId());
+                    createJson.put("creative_material_type", 1);  // 素材类型
+                } else {
+                    createJson.put("creative_material_type", video.getMaterialType());//1:竖版视频 2:横版视频
                 }
             }
             if (!Check.isNull(creativePreview.getImageTokens())) {
                 createJson.put("image_tokens", Arrays.asList(creativePreview.getImageTokens()));
                 createJson.put("creative_material_type", creativePreview.getMaterialType());
             }
-
-            if (!Check.isNull(creativePreview.getImageTokens())) {
-
-                createJson.put("photo_id", creativePreview.getPhotoId());  // 视频ID
-                KuaiShouVideoGet video = videoGetService.getVideoByPhotoId(Long.valueOf(creativePreview.getPhotoId()));
-                if (!Check.isNull(video)) {
-                    createJson.put("creative_material_type", video.getMaterialType());  // 素材类型
-                }
-            }
-
             if (!Check.isNull(creativePreview.getActionBarText())) {
                 createJson.put("action_bar_text", creativePreview.getActionBarText());  // 行动号召按钮文案
             }
@@ -454,6 +461,98 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
             if (!Check.isNull(creativePreview.getCreativeTag())) {
                 createJson.put("creative_tag", JSONObject.parseArray(creativePreview.getCreativeTag()));  // 创意标签
             }
+
+            Map<String, Object> creativeMap = kuaishouInterfaceService.creativeCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), createJson, 1);
+            JSONObject returnJson = new JSONObject();
+            Integer code = (Integer) creativeMap.get("code");
+            if (code == 0) {
+                Long creativeId = (Long) creativeMap.get("creativeId");
+                updateStatus.setIsSuccess(1);
+                updateStatus.setMessage((String) creativeMap.get("message"));
+                updateStatus.setCreativeId(creativeId);
+            } else {
+                updateStatus.setIsSuccess(0);
+                updateStatus.setMessage((String) creativeMap.get("message"));
+            }
+        } catch (Exception e) {
+            log.error("创建广告创意过程中调用快手接口异常", e);
+            updateStatus.setIsSuccess(0);
+            updateStatus.setMessage("创建广告创意过程中调用快手接口异常");
+        }
+        creativePreviewMapper.updateById(updateStatus);
+    }
+
+    /**
+     * 执行多线程创建程序化创意
+     */
+    private void createCopyProgramCreatives(CtopOauthToken token, List<KuaishouBatchCreativePreview> creativePreviewList, Long unitId, Long campaignId) {
+        creativePreviewList.forEach(creative -> campaignService.submit(() -> {
+            try {
+                createCopyProgramCreatives(token, campaignId, unitId, creative);
+            } catch (Exception e) {
+                log.error("根据预览数据创建广告创意异常", e);
+            }
+        }));
+    }
+
+    /**
+     * 根据预览数据创建程序化广告创意
+     */
+    private void createCopyProgramCreatives(CtopOauthToken oauthToken, Long campaignId, Long unitId, KuaishouBatchCreativePreview creativePreview) throws Exception {
+        KuaishouBatchCreativePreview updateStatus = new KuaishouBatchCreativePreview();
+        updateStatus.setId(creativePreview.getId());
+        updateStatus.setCampaignId(campaignId);
+        updateStatus.setUnitId(unitId);
+        try {
+            JSONObject createJson = new JSONObject();
+            createJson.put("advertiser_id", oauthToken.getAccountId());
+            createJson.put("unit_id", unitId);
+            createJson.put("package_name", creativePreview.getCreativeName()); // 创意名称
+            if (!Check.isNull(creativePreview.getPhotoId())) {
+                JSONArray photoList = new JSONArray();
+                List<String> photoIds = JSONObject.parseArray(creativePreview.getPhotoId(), String.class);
+                for (String photoId : photoIds) {
+                    JSONObject photo = new JSONObject();
+                    photo.put("photo_id", photoId);//视频 ID
+                    photo.put("cover_image_token", null);//封面图片 token,通过上传图片接口获得,不传值则直接使用视频的首帧作为封面图片
+                    KuaiShouVideoGet video = videoGetService.getVideoByPhotoId(Long.valueOf(photoId));
+                    if (Check.isNull(video)) {
+                        log.info("账户:{},photoId:{} 没有查询到视频,素材类型指定为竖版视频", oauthToken.getAccountId(), photoId);
+                        photo.put("creative_material_type", 1);
+                    } else {
+                        photo.put("creative_material_type", video.getMaterialType());//1:竖版视频 2:横版视频
+                    }
+                    photoList.add(photo);
+                }
+                createJson.put("photo_list", photoList);
+            }
+            if (!Check.isNull(creativePreview.getImageTokens())) {
+                createJson.put("pic_list", JSONObject.parseArray(creativePreview.getImageTokens()));
+            }
+            if (!Check.isNull(creativePreview.getDescription())) {
+                createJson.put("captions", JSONObject.parseArray(creativePreview.getDescription()));  // 广告语
+            }
+            if (!Check.isNull(creativePreview.getActionBarText())) {
+                createJson.put("action_bar", creativePreview.getActionBarText());  // 行动号召按钮文案
+            }
+            if (!Check.isNull(creativePreview.getSiteId())) {
+                createJson.put("site_id", creativePreview.getSiteId());  // 安卓下载中间页ID
+            }
+            if (!Check.isNull(creativePreview.getClickTrackUrl())) {
+                createJson.put("click_url", creativePreview.getClickTrackUrl());  // 第三方点击检测链接
+            }
+            if (!Check.isNull(creativePreview.getAdPhotoPlayedT3sUrl())) {
+                createJson.put("ad_photo_played_t3s_url", creativePreview.getAdPhotoPlayedT3sUrl());  // 第三方有效播放监测链接
+            }
+            if (!Check.isNull(creativePreview.getActionbarClickUrl())) {
+                createJson.put("actionbar_click_url", creativePreview.getActionbarClickUrl());  // 第三方点击按钮监测链接
+            }
+            if (!Check.isNull(creativePreview.getCreativeCategory())) {
+                createJson.put("creative_category", creativePreview.getCreativeCategory());  // 创意分类
+            }
+            if (!Check.isNull(creativePreview.getCreativeTag())) {
+                createJson.put("creative_tag", JSONObject.parseArray(creativePreview.getCreativeTag()));  // 创意标签
+            }
             Integer outerLoopNative = creativePreview.getOuterLoopNative();
             if (!Check.isNull(outerLoopNative)) {
                 createJson.put("outer_loop_native", outerLoopNative);
@@ -461,15 +560,7 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
                     createJson.put("kol_user_type", creativePreview.getKolUserType());
                 }
             }
-            String image_md5 = creativePreview.getImageSignature();
-            String imageToken = null;
-            if (!Check.isNull(image_md5)) {
-                imageToken = getImageToken(image_md5, oauthToken.getAccountId(), oauthToken.getAccessToken());
-            }
-            if (!Check.isNull(imageToken)) {
-                createJson.put("image_token", imageToken); // 自定义创意封面token
-            }
-            Map<String, Object> creativeMap = kuaishouInterfaceService.creativeCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), createJson, 1);
+            Map<String, Object> creativeMap = this.createProgramCreatives(oauthToken.getAccountId(), oauthToken.getAccessToken(), createJson, 1);
             JSONObject returnJson = new JSONObject();
             Integer code = (Integer) creativeMap.get("code");
             if (code == 0) {
@@ -482,7 +573,7 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
                 updateStatus.setMessage((String) creativeMap.get("message"));
             }
         } catch (Exception e) {
-            log.error("创建广告创意过程中调用快手接口异常", e);
+            log.error("创建程序化广告创意过程中调用快手接口异常", e);
             updateStatus.setIsSuccess(0);
             updateStatus.setMessage("创建广告创意过程中调用快手接口异常");
         }
@@ -514,4 +605,56 @@ public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<Kuaisho
         }
         return imageToken;
     }
+
+    /**
+     * 创建程序化创意
+     */
+    private Map<String, Object> createProgramCreatives(Long accountId, String token, JSONObject creativeParams, int count) {
+        Map<String, Object> returnMap = new HashMap<>();
+        try {
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Content-Type", "application/json");
+            headers.put("Access-Token", token);
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.PROGRAM_CREATE;
+            String result = HttpUtils.kuaiShouhttpPostRequest(url, creativeParams.toJSONString(), headers);
+            JSONObject resultJson = JSON.parseObject(result);
+            if (Check.isNull(resultJson)) {
+                log.error("【批量工具】程序化创意创意异常:api接口返回为空");
+                returnMap.put("code", -1);
+                returnMap.put("message", "程序化创意创意异常:api接口返回为空");
+                returnMap.put("success", false);
+                return returnMap;
+            }
+            Integer code = resultJson.getInteger("code");
+            String message = resultJson.getString("message");
+            Long unitId = creativeParams.getLong("unit_id");
+            if (code == 0) {
+                returnMap.put("code", 0);
+                returnMap.put("message", "success");
+                returnMap.put("success", true);
+            } else {
+                log.error("【批量工具】程序化创意创建失败,账户ID:{},返回结果:{},------入参:{}", accountId, resultJson, creativeParams);
+                if ("系统错误".equals(message) && count <= 4) {
+                    log.info("第{}次重新创建程序化创意", count);
+                    //系统错误,则重新执行
+                    return createProgramCreatives(accountId, token, creativeParams, count + 1);
+                }
+                if (message.contains("过于频繁") && count <= 4) {
+                    Thread.sleep(1000);
+                    //该请求接口「/rest/openapi/v2/creative/advanced/program/create」过于频繁,则重新执行
+                    return createProgramCreatives(accountId, token, creativeParams, count + 1);
+                }
+                returnMap.put("code", -1);
+                returnMap.put("message", resultJson.getString("message"));
+                returnMap.put("success", false);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("【批量工具】执行程序化创意创建异常", e);
+            returnMap.put("code", -1);
+            returnMap.put("message", "执行程序化创意创建异常");
+            returnMap.put("success", false);
+        }
+        return returnMap;
+    }
 }

+ 131 - 30
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouInterfaceServiceImpl.java

@@ -10,18 +10,68 @@ import cn.com.ctop.common.module.service.IMaterialCutFrameService;
 import cn.com.ctop.common.module.service.IMessageTemplate;
 import cn.com.ctop.common.module.service.IOauthConfigService;
 import cn.com.ctop.common.module.service.IUserAllocationService;
-import cn.com.ctop.common.module.utils.*;
-import cn.com.ctop.kuaishou.modules.ai.service.*;
-import cn.com.ctop.kuaishou.modules.batch.entity.*;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.CtopAdConstant;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.common.module.utils.JsonUtil;
+import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
+import cn.com.ctop.common.module.utils.PropertiesUtils;
+import cn.com.ctop.kuaishou.modules.ai.service.IAiCreativeLimitService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouAccountCreativeOverrunInfoService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouAppPackageService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouDirectionalPackageService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouLandpagePackageService;
+import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouPopulationGroupService;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouAdvertiserBaseInfo;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouAppList;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCampaign;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouCreative;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouDailyFlows;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouRegionListChildren;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouRegionListParent;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouTargetingTags;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouPopulation;
 import cn.com.ctop.kuaishou.modules.batch.entity.vo.ConvertVo;
-import cn.com.ctop.kuaishou.modules.batch.mapper.*;
-import cn.com.ctop.kuaishou.modules.batch.service.*;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouAdvertiserBaseInfoMapper;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouAppListMapper;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouGroupMapper;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouRegionListChildrenMapper;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouRegionListParentMapper;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouTargetingTagsMapper;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCampaignService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCreativeService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouDailyFlowsService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouHistoryReportTaskService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouOverRunSendMessageService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouPopulationService;
+import cn.com.ctop.kuaishou.modules.batch.service.IWarningOperationService;
 import cn.com.ctop.kuaishou.modules.material.entity.KuaishouResult;
 import cn.com.ctop.kuaishou.modules.material.entity.KuaishouResultToken;
-import cn.com.ctop.kuaishou.modules.report.entity.*;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyAccount;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyCampaign;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyCreative;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyCreativeStatistic;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportHourlyAccount;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportHourlyCampaign;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportHourlyCreative;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportHourlyCreativeStatistic;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportHourlyGroup;
 import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouReportDailyAccountMapper;
 import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouReportDailyCampaignMapper;
-import cn.com.ctop.kuaishou.modules.report.service.*;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyCampaignService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyCreativeService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportHourlyAccountService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportHourlyCampaignService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportHourlyCreativeService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportHourlyGroupService;
+import cn.com.ctop.kuaishou.modules.report.service.IRuleKuaiShouPlanService;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -56,7 +106,11 @@ import java.io.IOException;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -136,7 +190,8 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
     private KuaiShouOcpxActionTypeConfigMapper ocpxActionTypeConfigMapper;
     @Autowired
     private IMessageTemplate messageTemplate;
-
+    @Autowired
+    private RedisUtil redisUtil;
     private static ExecutorService cutExecutorService = Executors.newFixedThreadPool(10);
 
     @Override
@@ -886,10 +941,8 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                     // 创建成功 拉取广告组信息
                     Thread.sleep(100);
                     getCampaign(accessToken, advertiserId, campaignId);
-
-
                 } else {
-                    log.error("创建广告计划失败,advertiser_id:{},返回信息:{}", advertiserId, resultJson);
+                    log.error("创建[广告计划]失败,账户ID:{},返回结果:{},------入参:{}", advertiserId, resultJson, requestJson);
                     returnMap.put("code", -1);
                     returnMap.put("message", resultJson.getString("message"));
                     returnMap.put("desc", "创建广告计划失败");
@@ -920,11 +973,6 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
      * @param requestJson
      * @return
      */
-
-
-    @Autowired
-    private RedisUtil redisUtil;
-
     @Override
     public Map<String, Object> adUnitCreate(String accessToken, Long advertiserId, JSONObject requestJson, Integer count) {
         Map<String, Object> returnMap = new HashMap<>();
@@ -939,7 +987,7 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
             headers.put("Content-Type", " application/json");
             String result = HttpUtils.kuaiShouhttpPostRequest(url, requestJson.toJSONString(), headers);
             JSONObject resultJson = JSONObject.parseObject(result);
-            log.info("快手创建广告组返回,accountId:{},返回结果:{}", advertiserId, resultJson);
+            log.info("【快手】建组返回,accountId:{},---结果:{}", advertiserId, resultJson);
             if (!Check.isNull(resultJson)) {
                 Integer code = resultJson.getInteger("code");
                 if (code == 0) {
@@ -994,12 +1042,11 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                         String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
                         String key = advertiserId + "_" + nowDate + "unit_create_overrun";
                         redisUtil.set(key, 1, 60 * 60 * 24);
-
                     }
                     if (code == 500000 && count <= 4) {
                         adUnitCreate(accessToken, advertiserId, requestJson, count + 1);
                     }
-                    log.error("创建广告信息失败,advertiser_id:{},返回信息:{},入参:{}", advertiserId, resultJson, requestJson);
+                    log.error("创建[广告组]失败,账户ID:{},返回结果:{},------入参:{}", advertiserId, resultJson, requestJson);
                     returnMap.put("code", -1);
                     returnMap.put("message", resultJson.getString("message"));
                     returnMap.put("desc", "创建广告组失败");
@@ -1017,7 +1064,7 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                 returnMap.put("success", false);
             }
         } catch (Exception e) {
-            log.error("创建广告计划失败,advertiser_id:{}", advertiserId);
+            log.error("创建广告失败,advertiser_id:{}", advertiserId);
             returnMap.put("code", -1);
             returnMap.put("message", "创建广告组错误");
             returnMap.put("desc", "Interface exception");
@@ -2128,10 +2175,9 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
             Map<String, String> header = new HashMap<String, String>();
             header.put("Content-Type", " application/json");
             header.put("Access-Token", accessToken);
-
             String result = HttpUtils.kuaiShouhttpPostRequest(url, requestJson.toJSONString(), header);
             JSONObject resultJson = JSONObject.parseObject(result);
-            log.info("快手创建创意返回:accountId:{},返回结果{}", advertiserId, resultJson);
+            log.info("【快手】建创意返回,accountId:{},---结果:{}", advertiserId, resultJson);
             if (!Check.isNull(resultJson)) {
                 Integer code = resultJson.getInteger("code");
                 if (code == 0) {
@@ -2165,24 +2211,20 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                     if (code == 500000 && count <= 4) {
                         creativeCreate(accessToken, advertiserId, requestJson, count + 1);
                     }
-
                     if (code == 400001 && "/rest/openapi/v2/creative/create调用已超日限,次日可恢复调用".equals(resultJson.getString("message"))) {
                         creativeOverrunInfoService.updateOverrunInfo(advertiserId);
                         overRunSendMessageService.creativeOverRunSendMessage(advertiserId, null);
                         String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
                         String key = advertiserId + "_" + nowDate + "creative_create_overrun";
                         redisUtil.set(key, 1, 60 * 60 * 24);
-
-
                     }
-
                     if (code == 401000 && resultJson.getString("message").contains("超过可关联的有效创意的上限")) {
                         creativeLimitService.replaceSava(advertiserId, requestJson.getLong("photo_id"));
                     }
                     if (code == 401000 && resultJson.getString("message").contains("视频不存在")) {
                         creativeLimitService.replaceSava(advertiserId, requestJson.getLong("photo_id"));
                     }
-                    log.error("创建广告创意失败,advertiser_id:{},返回信息:{},入参:{}", advertiserId, resultJson, requestJson, count + 1);
+                    log.error("创建[广告创意]失败,账户ID:{},返回结果:{},------入参:{}", advertiserId, resultJson, requestJson);
                     returnMap.put("code", -1);
                     returnMap.put("message", resultJson.getString("message"));
                     returnMap.put("desc", "创意创建失败");
@@ -2192,7 +2234,6 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
                 if (count <= 4) {
                     creativeCreate(accessToken, advertiserId, requestJson, count + 1);
                 }
-
                 log.error("快手创建广告创意返回内容为空,advertiser_id:{},入参:{}", advertiserId, requestJson);
                 returnMap.put("code", -1);
                 returnMap.put("message", "result is null");
@@ -2907,6 +2948,67 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
 
     }
 
+    /**
+     * 获取联盟定向媒体包列表
+     *
+     * @param accountId
+     * @param accessToken
+     * @return
+     */
+    @Override
+    public void getMediaList(Long accountId, String accessToken, Integer page) {
+        List<JSONObject> list = new ArrayList<>();
+        try {
+            log.info("获取人群包列表,accountId:{}", accountId);
+            String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.MEDIA_LIST;
+            Map<String, String> headers = new HashMap<>();
+            headers.put("Access-Token", accessToken);
+            headers.put("Content-Type", "application/json");
+            JSONObject requestJson = new JSONObject();
+            requestJson.put("advertiser_id", accountId);
+            requestJson.put("page", page);
+            requestJson.put("page_size", 50);
+            String result = HttpUtils.kuaiShouhttpPostRequest(url, requestJson.toJSONString(), headers);
+            JSONObject resultJson = JSONObject.parseObject(result);
+            if (!Check.isNull(resultJson)) {
+                Integer code = resultJson.getInteger("code");
+                if (code == 0) {
+                    JSONObject dataDetailJson = resultJson.getJSONObject("data");
+                    if (Check.isNull(dataDetailJson)) {
+                        return;
+                    }
+                    JSONArray details = dataDetailJson.getJSONArray("details");
+                    if (Check.isNull(details)) {
+                        return;
+                    }
+                    for (int i = 0; i < details.size(); i++) {
+                        JSONObject jsonObject = details.getJSONObject(i);
+                        JSONObject media = jsonObject.getJSONObject("media");
+                        if (!Check.isNull(media)) {
+                            media.put("posIds", media.getString("posIds"));
+                            media.put("accountId", accountId);
+                            list.add(media);
+                        }
+                    }
+                    if (!list.isEmpty()) {
+                        populationService.replaceBatchMedia(list);
+                    }
+                    if (list.size() >= 50) {
+                        getMediaList(accountId, accessToken, page + 1);
+                    }
+                } else {
+                    log.error("获取联盟定向媒体包列表失败,accountId:{},返回:{}", accountId, resultJson);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public List<JSONObject> getMedias(Long accountId) {
+        return populationService.getMedias(accountId);
+    }
 
     /**
      * 获取定向标签
@@ -3525,5 +3627,4 @@ public class KuaishouInterfaceServiceImpl implements IKuaishouInterfaceService {
         return returnJson;
     }
 
-
 }

+ 10 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouPopulationServiceImpl.java

@@ -358,4 +358,14 @@ public class KuaishouPopulationServiceImpl extends ServiceImpl<KuaishouPopulatio
         populationMapper.deleteByAccountId(addList.get(0).getAccountId());
         populationMapper.replaceBatch(addList);
     }
+
+    @Override
+    public void replaceBatchMedia(List<JSONObject> list) {
+        populationMapper.replaceBatchMedia(list);
+    }
+
+    @Override
+    public List<JSONObject> getMedias(Long accountId) {
+        return populationMapper.getMedias(accountId);
+    }
 }

+ 3 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaishouTemplateServiceImpl.java

@@ -114,6 +114,9 @@ public class KuaishouTemplateServiceImpl extends ServiceImpl<KuaishouTemplateMap
                         if (!Check.isNull(targetJson.getInteger("gender"))) {
                             templateTarget.setGender(targetJson.getInteger("gender"));
                         }
+                        if (!Check.isNull(targetJson.getInteger("disable_installed_app_switch"))) {
+                            templateTarget.setDisableInstalledAppSwitch(targetJson.getInteger("disable_installed_app_switch"));
+                        }
                         if (!Check.isNull(targetJson.getInteger("platform_os"))) {
                             templateTarget.setPlatformOs(targetJson.getInteger("platform_os"));
                         }

+ 1 - 0
jeecg-boot-module-system/src/main/java/cn/com/ctop/kuaishou/modules/clean/service/impl/TrackMonitorConfigureServiceImpl.java

@@ -21,6 +21,7 @@ public class TrackMonitorConfigureServiceImpl extends ServiceImpl<TrackMonitorCo
     public TrackMonitorConfigure getByAccountId(Long accountId) {
         QueryWrapper<TrackMonitorConfigure> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("account_id", accountId);
+        queryWrapper.last("limit 1");
         return this.getOne(queryWrapper);
     }
 }

+ 8 - 6
jeecg-boot-module-system/src/main/java/cn/com/ctop/reimburse/mondule/entity/ReimburseProject.java

@@ -1,21 +1,17 @@
 package cn.com.ctop.reimburse.mondule.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.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 com.fasterxml.jackson.annotation.JsonFormat;
-import org.springframework.format.annotation.DateTimeFormat;
 import org.jeecgframework.poi.excel.annotation.Excel;
 
+import java.util.Date;
+
 /**
  * 报销申请项目表
  *
@@ -79,6 +75,12 @@ public class ReimburseProject {
     @ApiModelProperty(value = "文件链接集合")
     private Object fileUrls;
     /**
+     * 文件链接集合
+     */
+    @Excel(name = "excel链接集合", width = 15)
+    @ApiModelProperty(value = "excel链接集合")
+    private Object excelUrls;
+    /**
      * 备注
      */
     @Excel(name = "备注", width = 15)