浏览代码

Merge remote-tracking branch 'origin/test'

songyh 4 年之前
父节点
当前提交
7aeb1466ff
共有 54 个文件被更改,包括 1903 次插入172 次删除
  1. 27 0
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
  2. 15 5
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/dockapi/MarketingServiceImpl.java
  3. 3 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/AiBytedanceAdDplinkInfo.java
  4. 69 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/AiBytedanceAutocreateLog.java
  5. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/ByteDanceVideoInfo.java
  6. 27 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceMaterialRejectReason.java
  7. 22 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedancePlanRejectReason.java
  8. 8 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceVideoSlogenInfo.java
  9. 19 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/LowQualityRejectReason.java
  10. 43 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/enums/BytedanceCreativeMatTypeEnum.java
  11. 1 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/AiBytedanceAdvertiserStrategyMapper.java
  12. 17 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/AiBytedanceAutocreateLogMapper.java
  13. 5 2
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceGeneralCopywriterMapper.java
  14. 23 3
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceVideoInfoMapper.java
  15. 17 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/BytedanceMaterialRejectReasonMapper.java
  16. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/BytedancePlanRejectReasonMapper.java
  17. 3 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/BytedanceVideoSlogenInfoMapper.java
  18. 15 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/LowQualityRejectReasonMapper.java
  19. 3 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/AiBytedanceAdvertiserStrategyMapper.xml
  20. 5 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/AiBytedanceAutocreateLogMapper.xml
  21. 16 3
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceGeneralCopywriterMapper.xml
  22. 125 5
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceVideoInfoMapper.xml
  23. 12 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/BytedanceMaterialRejectReasonMapper.xml
  24. 9 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/BytedancePlanRejectReasonMapper.xml
  25. 16 2
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/BytedanceVideoSlogenInfoMapper.xml
  26. 9 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/LowQualityRejectReasonMapper.xml
  27. 19 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/BytedanceRejectReasonService.java
  28. 2 2
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IAiBytedanceAdDplinkInfoService.java
  29. 7 3
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IAiBytedanceAdvertiserStrategyService.java
  30. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IAiBytedanceAutocreateLogService.java
  31. 2 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceAdvertisePlanService.java
  32. 0 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceCreativeService.java
  33. 5 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceGeneralCopywriterService.java
  34. 26 3
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceVideoInfoService.java
  35. 3 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IBytedanceVideoSlogenInfoService.java
  36. 6 2
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/AiBytedanceAdDplinkInfoServiceImpl.java
  37. 306 69
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/AiBytedanceAdvertiserStrategyServiceImpl.java
  38. 19 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/AiBytedanceAutocreateLogServiceImpl.java
  39. 14 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceAdvertisePlanServiceImpl.java
  40. 7 2
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceGeneralCopywriterServiceImpl.java
  41. 35 6
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceVideoInfoServiceImpl.java
  42. 131 0
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/BytedanceRejectReasonServiceImpl.java
  43. 6 2
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/BytedanceVideoSlogenInfoServiceImpl.java
  44. 1 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/IMaterialInfoService.java
  45. 4 1
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/MaterialInfoServiceImpl.java
  46. 3 3
      jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/GetCampaignNum.java
  47. 31 11
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/AiBytedanceAdvertiserStrategyController.java
  48. 95 14
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/BytedanceGeneralCopywriterController.java
  49. 111 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/BytedanceRejectReasonController.java
  50. 83 22
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/BytedanceVideoSlogenInfoController.java
  51. 37 1
      jeecg-boot-module-system/src/main/resources/application-dev.yml
  52. 329 0
      jeecg-boot-module-system/src/main/resources/application-pre.yml
  53. 41 2
      jeecg-boot-module-system/src/main/resources/application-prod.yml
  54. 38 2
      jeecg-boot-module-system/src/main/resources/application-test.yml

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

@@ -640,4 +640,31 @@ public class DateUtils extends PropertyEditorSupport {
         return calendar.get(Calendar.YEAR);
     }
 
+    public static String addDay(String dateString, int day) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        Date date = null;
+        try {
+            date = sdf.parse(dateString);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.DAY_OF_YEAR, day);
+        return sdf.format(calendar.getTime());
+    }
+
+    public static Date addDay(Date date, int day) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.DAY_OF_YEAR, day);
+        return calendar.getTime();
+    }
+
+    public static Date addHour(Date date, int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.add(Calendar.HOUR_OF_DAY, hour);
+        return calendar.getTime();
+    }
 }

+ 15 - 5
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/dockapi/MarketingServiceImpl.java

@@ -11,8 +11,10 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAdvertiserStrategy;
+import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAutocreateLog;
 import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCampaign;
 import org.jeecg.modules.bytedance.advertise.enums.BytedanceConvertType;
+import org.jeecg.modules.bytedance.advertise.service.IAiBytedanceAutocreateLogService;
 import org.jeecg.modules.bytedance.advertise.service.IByteDanceCampaignService;
 import org.jeecg.modules.bytedance.advertise.vo.AdConvertQueryVo;
 import org.jeecg.modules.bytedance.advertise.vo.ByteDanceSearchVo;
@@ -47,6 +49,9 @@ public class MarketingServiceImpl implements MarketingService{
 
     @Autowired
     private IByteDanceCampaignService campaignService;
+
+    @Autowired
+    IAiBytedanceAutocreateLogService iBytedanceAutocreateLogService;
     /**
      *
      * @description: 获取账户日预算
@@ -425,24 +430,29 @@ public class MarketingServiceImpl implements MarketingService{
      * @author: zianY
      */
     @Override
-    public  Result getRejectReason(CtopOauthToken token, String advertiserId, List<String> adIds) {
+    public Result getRejectReason(CtopOauthToken token, String advertiserId, List<String> adIds) {
         JSONObject params = new JSONObject();
         params.put("advertiser_id", advertiserId);
         params.put("ad_ids", adIds);
 
         JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
-                urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_create_reasion"),params);
+                urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_create_reasion"), params);
         Integer code = jsonObject.getInteger("code");
         if (null == code || !code.equals(0)) {
-            log.info("获取广告主计划审核建议接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
-            return Result.error("获取广告主计划审核建议接口异常");
+//            log.info("获取广告主计划审核建议接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            if (jsonObject.getString("message").toString().contains("ad_ids:[")) {
+                JSONArray ad_ids = JSONArray.parseArray(jsonObject.getString("message").toString().split(":")[2]);
+                adIds.removeAll(ad_ids.toJavaList(String.class));
+                return getRejectReason(token, advertiserId, adIds);
+            }
+            return Result.error("获取广告主计划审核建议接口异常==》message:"+jsonObject.getString("message"));
         }
         JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
         if (null == data || data.isEmpty()) {
             log.info("获取广告主计划审核建议不存在==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
             return Result.error("获取广告主计划审核建议不存在");
         }
-        return Result.successMsg("获取广告主计划审核建议成功。",data);
+        return Result.successMsg("获取广告主计划审核建议成功。", data);
     }
 
 

+ 3 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/AiBytedanceAdDplinkInfo.java

@@ -29,6 +29,9 @@ public class AiBytedanceAdDplinkInfo {
 	private Long adId;
 	/**accountId*/
 	private Long accountId;
+
+	private String imageMode;
+
 	private BigDecimal adBid;
 	/**strategyId*/
 	private Long strategyId;

+ 69 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/AiBytedanceAutocreateLog.java

@@ -0,0 +1,69 @@
+package org.jeecg.modules.bytedance.advertise.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;
+
+
+/**
+ * 自动创建计划日志
+ * @author jeecg-boot
+ * @date   2021-07-05
+ * @version V1.0
+ */
+@Data
+@TableName("ctop_ai_bytedance_autocreate_log")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="ctop_ai_bytedance_autocreate_log对象", description="自动创建计划日志")
+public class AiBytedanceAutocreateLog {
+
+	/**主键id*/
+	@TableId(type = IdType.AUTO)
+	@ApiModelProperty(value = "主键id")
+	private Integer id;
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+	@ApiModelProperty(value = "账户id")
+	private Long accountId;
+	/**类型*/
+	@Excel(name = "类型", width = 15)
+	@ApiModelProperty(value = "类型")
+	private String execType;
+	/**代码*/
+	@Excel(name = "代码", width = 15)
+	@ApiModelProperty(value = "代码")
+	private Integer code;
+	/**返回消息*/
+	@Excel(name = "返回消息", width = 15)
+	@ApiModelProperty(value = "返回消息")
+	private String message;
+	/**创建调用接口的参数*/
+	@Excel(name = "创建调用接口的参数", width = 15)
+	@ApiModelProperty(value = "创建调用接口的参数")
+	private String createParam;
+	/**创建时间*/
+	@ApiModelProperty(value = "创建时间")
+	private Date createTime;
+
+	public AiBytedanceAutocreateLog(){}
+
+	public AiBytedanceAutocreateLog(Long accountId, String execType, Integer code, String message, String createParam){
+		this.accountId = accountId;
+		this.execType = execType;
+		this.code = code;
+		this.message = message;
+		this.createParam = createParam;
+	}
+}

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

@@ -80,6 +80,11 @@ public class ByteDanceVideoInfo {
     private String filename;
     private Integer type;
 
+
+    //素材类型  video-视频;image-图片
+    private String materialType;
+
+
     public ByteDanceVideoInfo(JSONObject data, CtopOauthToken token) {
         this.id = data.getString("id")+token.getAccountId();
         this.vid = data.getString("id");

+ 27 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceMaterialRejectReason.java

@@ -0,0 +1,27 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@TableName("ctop_bytedance_material_reject_reason")
+public class BytedanceMaterialRejectReason {
+    private String videoId;
+
+    private String imageId;
+
+    private String title;
+
+    private String rejectReason;
+
+    private Integer isLowQuality;
+
+    private Date createTime;
+
+    private Long accountId;
+
+    private Long adId;
+}

+ 22 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedancePlanRejectReason.java

@@ -0,0 +1,22 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@TableName("ctop_bytedance_plan_reject_reason")
+public class BytedancePlanRejectReason {
+    private Long adId;
+
+    private String rejectItem;
+
+    private String rejectReason;
+
+    private Integer isLowQuality;
+
+    private Date createTime;
+
+    private Long accountId;
+
+}

+ 8 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/BytedanceVideoSlogenInfo.java

@@ -1,11 +1,13 @@
 package org.jeecg.modules.bytedance.advertise.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * 头条视频文案信息
@@ -22,8 +24,14 @@ public class BytedanceVideoSlogenInfo {
 	private Long id;
 	/**videoCode*/
 	private String videoCode;
+	@TableField(exist=false)
+	private String materialName;
+	@TableField(exist=false)
+	private List<String> materialNameArray;
 	/**slogan*/
 	private String slogan;
+	@TableField(exist=false)
+	private String newSlogan;
 	/**createTime*/
 	private Date createTime;
 	/**updateTime*/

+ 19 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/entity/LowQualityRejectReason.java

@@ -0,0 +1,19 @@
+package org.jeecg.modules.bytedance.advertise.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.util.Date;
+
+
+@Data
+@TableName("ctop_low_quality_reject_reason")
+public class LowQualityRejectReason {
+    private Integer id;
+
+    private String auditRejectReason;
+
+    private Integer status;
+
+    private Date createTime;
+}

+ 43 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/enums/BytedanceCreativeMatTypeEnum.java

@@ -8,7 +8,20 @@ public enum BytedanceCreativeMatTypeEnum {
     BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_NEW("1","上新",0L,0L),
     BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_HIGH_QUALITY("2","高质量",-4*60*24L,-1*60*24L),
     BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_MISSING("3","遗漏",-8*60*24L,-1*60*24L),
-    BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_HISTORY("4","打捞",-8*60*24L,-1*60*24L);
+    BYTEDANCE_CREATIVE_MAT_TYPE_ENUM_HISTORY("4","打捞",-8*60*24L,-1*60*24L),
+
+
+
+
+    BYTEDANCE_CREATIVE_IMAGE_MODE_LARGE("CREATIVE_IMAGE_MODE_LARGE","1","大图横图"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_LARGE_VERTICAL("CREATIVE_IMAGE_MODE_LARGE_VERTICAL","2","大图竖图"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_UNION_SPLASH("CREATIVE_IMAGE_MODE_UNION_SPLASH","3","开屏"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_VIDEO("CREATIVE_IMAGE_MODE_VIDEO","2","横版视频"),
+    BYTEDANCE_CREATIVE_IMAGE_MODE_VIDEO_VERTICAL("CREATIVE_IMAGE_MODE_VIDEO_VERTICAL","1","竖版视频");
+
+
+
+
 
     /**
      * 类型
@@ -24,6 +37,8 @@ public enum BytedanceCreativeMatTypeEnum {
     private Long videoGetStartTime;
     private Long videoGetEndTime;
 
+    private String imageMode;
+
     BytedanceCreativeMatTypeEnum(String type, String name,Long videoGetStartTime,Long videoGetEndTime) {
         this.type = type;
         this.name = name;
@@ -89,4 +104,31 @@ public enum BytedanceCreativeMatTypeEnum {
     public void setVideoGetEndTime(Long videoGetEndTime) {
         this.videoGetEndTime = videoGetEndTime;
     }
+
+
+    public String getImageMode() {
+        return imageMode;
+    }
+
+    public void setImageMode(String imageMode) {
+        this.imageMode = imageMode;
+    }
+
+
+    BytedanceCreativeMatTypeEnum(String type, String name,String imageMode) {
+        this.type = type;
+        this.name = name;
+        this.imageMode = imageMode;
+    }
+
+
+    public static String getImageModeByType(String type) {
+        for (BytedanceCreativeMatTypeEnum createTypeEnum : BytedanceCreativeMatTypeEnum.values()) {
+            if (createTypeEnum.getType().equals(type)) {
+                return createTypeEnum.getImageMode();
+            }
+        }
+        return "";
+    }
+
 }

+ 1 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/AiBytedanceAdvertiserStrategyMapper.java

@@ -14,7 +14,7 @@ import org.jeecg.modules.bytedance.advertise.entity.UpdAdStaOrCpaOrBudget;
 public interface AiBytedanceAdvertiserStrategyMapper extends BaseMapper<AiBytedanceAdvertiserStrategy> {
 
 
-    Integer updStaByAccountId(@Param("accountId") String accountId,@Param("state") String state,@Param("id") String id);
+    Integer updStaByAccountId(@Param("accountId") String accountId,@Param("creativeImageMode")String creativeImageMode,@Param("state") String state,@Param("id") String id);
 
     Integer updStaById(@Param("id") String id,@Param("state") String state);
 

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

@@ -0,0 +1,17 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAutocreateLog;
+
+/**
+ * 自动创建计划日志
+ * @author jeecg-boot
+ * 2021-07-05
+ * @version V1.0
+ */
+public interface AiBytedanceAutocreateLogMapper extends BaseMapper<AiBytedanceAutocreateLog> {
+
+}

+ 5 - 2
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceGeneralCopywriterMapper.java

@@ -15,9 +15,12 @@ import java.util.Map;
  * @version V1.0
  */
 public interface ByteDanceGeneralCopywriterMapper extends BaseMapper<ByteDanceGeneralCopywriter> {
-    List<Map<String,Object>> selectGeneralCopywriterReport(List<String> accountIds, String keyWord, String startTime, String endTime);
+    List<Map<String,Object>> selectGeneralCopywriterReport(List<String> accountIds, String keyWord, Integer status, String startTime, String endTime);
 
     ByteDanceCreativeWordPackage selectCreativeWordPackageByName(String name);
 
-    ByteDanceGeneralCopywriter getRandOne(@Param(value = "accountId") Long accountId);
+    List<ByteDanceGeneralCopywriter> getRandThree(@Param(value = "accountId") Long accountId);
+    List<ByteDanceGeneralCopywriter> getRandTen(@Param(value = "accountId") Long accountId);
+
+    List<ByteDanceGeneralCopywriter> selectAllDataByTextCopywriter(@Param(value = "textCopywriter") String textCopywriter);
 }

+ 23 - 3
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/ByteDanceVideoInfoMapper.java

@@ -25,9 +25,29 @@ public interface ByteDanceVideoInfoMapper extends BaseMapper<ByteDanceVideoInfo>
      * @param videoCnt
      * @return
      */
-    List<ByteDanceVideoInfo> getNewVideoByParams(@Param(value = "projectId") Long projectId,@Param(value = "accountId") Long accountId, @Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "creativeCnt")Long creativeCnt,@Param(value = "now") String now);
+    List<ByteDanceVideoInfo> getNewVideoByParams(@Param(value = "projectId") Long projectId,@Param(value = "accountId") Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "creativeCnt")Long creativeCnt,@Param(value = "now") String now);
+
+    List<ByteDanceVideoInfo> topMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+    List<ByteDanceVideoInfo>historyMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+
+    /**
+     *图片 上新 遗漏
+     */
+    List<ByteDanceVideoInfo> imageListByParams(@Param(value = "projectId") Long projectId,@Param(value = "accountId") Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "creativeCnt")Long creativeCnt,@Param(value = "now") String now);
+
+    /**
+     * 图片 跑量
+     */
+    List<ByteDanceVideoInfo> imageTopMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+    /**
+     * 图片 打捞
+     */
+    List<ByteDanceVideoInfo>imageHistoryMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "imageMode") String imageMode,@Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
+
+
 
-    List<ByteDanceVideoInfo> topMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
 
-    List<ByteDanceVideoInfo>historyMatByParams(@Param(value = "projectId")Long projectId, @Param(value = "accountId")Long accountId, @Param(value = "startTime")String startTime, @Param(value = "endTime")String endTime, @Param(value = "videoCnt")Long videoCnt,@Param(value = "now") String now);
 }

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

@@ -0,0 +1,17 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.BytedanceMaterialRejectReason;
+
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface BytedanceMaterialRejectReasonMapper extends BaseMapper<BytedanceMaterialRejectReason> {
+    int replaceIntoDb(BytedanceMaterialRejectReason bytedanceMaterialRejectReason);
+
+    Integer getIsLowQualityByVideoId(String video);
+}

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

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.BytedancePlanRejectReason;
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface BytedancePlanRejectReasonMapper extends BaseMapper<BytedancePlanRejectReason> {
+    int replaceIntoDb(BytedancePlanRejectReason bytedancePlanRejectReason);
+}

+ 3 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/BytedanceVideoSlogenInfoMapper.java

@@ -14,6 +14,8 @@ import java.util.Map;
  * @version V1.0
  */
 public interface BytedanceVideoSlogenInfoMapper extends BaseMapper<BytedanceVideoSlogenInfo> {
-    List<Map<String,Object>> selectVideoSlogenReportByAccountIdAndTitle(List<String> projectIds, String keyWord, String startTime, String endTime);
+    List<Map<String,Object>> selectVideoSlogenReportByAccountIdAndTitle(List<String> projectIds, String keyWord, Integer status, String startTime, String endTime);
     List<String> getProjectByUserId(String userId);
+
+    List<BytedanceVideoSlogenInfo> getDataBySlogenAndProjectId(String slogan, Long projectId);
 }

+ 15 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/LowQualityRejectReasonMapper.java

@@ -0,0 +1,15 @@
+package org.jeecg.modules.bytedance.advertise.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.bytedance.advertise.entity.LowQualityRejectReason;
+
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface LowQualityRejectReasonMapper extends BaseMapper<LowQualityRejectReason> {
+    LowQualityRejectReason getByRejectReason(String rejectReason);
+}

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

@@ -10,6 +10,9 @@
         <if test="accountId !=null and accountId != ''">
             AND account_id = #{accountId}
         </if>
+        <if test="creativeImageMode !=null and creativeImageMode != ''">
+            AND creative_image_mode = #{creativeImageMode}
+        </if>
         <if test="id !=null and id != ''">
             AND id != #{id}
         </if>

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

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

+ 16 - 3
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/ByteDanceGeneralCopywriterMapper.xml

@@ -7,6 +7,8 @@
 
 
         SELECT
+            a.id,
+            a.status,
             a.account_id as accountId,
             d.creative_id as creativeId,
             a.text_copywriter AS textCopywriter,
@@ -20,7 +22,8 @@
         LEFT JOIN ctop_bytedance_creative b ON a.text_copywriter = b.title and a.account_id = b.account_id
         LEFT JOIN ctop_bytedance_report_creative_daily d ON b.id = d.creative_id
         WHERE
-            a.`status` = 0
+            1 = 1
+            <if test="status!=null">and a.`status` = #{status}</if>
             <if test="keyWord!=null and keyWord!=''">and a.text_copywriter like concat('%',#{keyWord},'%')</if>
             <if test="startTime!=null and startTime!=''">and STR_TO_DATE(d.stat_datetime,'%Y-%m-%d') &gt;= STR_TO_DATE(#{startTime},'%Y-%m-%d')</if>
             <if test="endTime!=null and endTime!=''">and STR_TO_DATE(d.stat_datetime,'%Y-%m-%d') &lt;= STR_TO_DATE(#{endTime},'%Y-%m-%d')</if>
@@ -39,8 +42,18 @@
     <select id="selectCreativeWordPackageByName" resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreativeWordPackage">
         select * from ctop_bytedance_creative_word_package where name = #{name}
     </select>
-    <select id="getRandOne"
+    <select id="getRandThree"
             resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceGeneralCopywriter">
-        select * from ctop_bytedance_general_copywriter where account_id = #{accountId} order by rand() limit 1
+        select * from ctop_bytedance_general_copywriter where status = 1 and account_id = #{accountId} order by rand() limit 3
+    </select>
+
+    <select id="getRandTen"
+            resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceGeneralCopywriter">
+        select * from ctop_bytedance_general_copywriter where status = 1 and account_id = #{accountId} order by rand() limit 10
+    </select>
+
+    <select id="selectAllDataByTextCopywriter" resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceGeneralCopywriter">
+        select * from ctop_bytedance_general_copywriter where text_copywriter = #{textCopywriter}
+
     </select>
 </mapper>

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

@@ -71,13 +71,15 @@
         select distinct video.*,
         (select count(1) from ctop_bytedance_ai_video_creative_log l where l.video_code = video.signature and l.account_id = video.account_id and l.state_date = #{now}) as creativeNum,
         (select count(1) from ctop_bytedance_creative c where c.video_id = video.vid and c.account_id = '${accountId}') as creativeCnt,
-        (select count(1) from ctop_bytedance_video_slogen_info s where s.video_code = video.signature) as slogens
+        (select count(1) from ctop_bytedance_video_slogen_info s where s.video_code = video.signature) as slogens,
+         'video' As materialType
         from ctop_bytedance_video_info video
         left join ctop_material_info cmi on video.signature = cmi.code and cmi.project_id = #{projectId}
         where account_id = #{accountId}
         and cmi.code is not null
         and cmi.status = 1
         and cmi.offline_flag = 0
+        and video.type = #{imageMode}
         and material_upload_time &gt;= #{startTime}
         and material_upload_time &lt;= #{endTime}
         having creativeCnt &lt;= #{creativeCnt} and slogens >0 and creativeNum = 0
@@ -89,7 +91,8 @@
         a.totalCost,
         (select count(1) from ctop_bytedance_ai_video_creative_log l where l.video_code = video.signature and l.account_id = video.account_id and l.state_date = #{now}) as creativeNum,
         (select count(1) from ctop_bytedance_creative c where c.video_id = video.vid and c.account_id = '${accountId}') as creativeCnt,
-        (select count(1) from ctop_bytedance_video_slogen_info s where s.video_code = video.signature ) as slogens
+        (select count(1) from ctop_bytedance_video_slogen_info s where s.video_code = video.signature ) as slogens,
+         'video' As materialType
         from (select report.material_id, sum(cost) as totalCost
         from ctop_bytedance_report_material_daily report
         left join ctop_user_allocation cua on report.account_id = cua.account_id
@@ -98,7 +101,7 @@
         and report.stat_datetime &lt;= #{endTime}
         group by report.material_id
         order by sum(report.cost) desc ) a
-        left join (select distinct a.* from ctop_bytedance_video_info a where a.account_id = #{accountId})as video
+        left join (select distinct a.* from ctop_bytedance_video_info a where a.account_id = #{accountId} and a.type = #{imageMode})as video
         on a.material_id = video.material_id
         left join ctop_material_info cmi on cmi.code = video.signature and cmi.project_id = #{projectId}
         where cmi.id =1
@@ -117,7 +120,8 @@
                a.totalCost,
                (select count(1) from ctop_bytedance_ai_video_creative_log l where l.video_code = video.signature and l.account_id = video.account_id and l.state_date = #{now}) as creativeNum,
                (select count(1) from ctop_bytedance_creative c where c.video_id = video.vid and c.account_id = '${accountId}') as creativeCnt,
-               (select count(1) from ctop_bytedance_video_slogen_info s where s.video_code = video.signature) as slogens
+               (select count(1) from ctop_bytedance_video_slogen_info s where s.video_code = video.signature) as slogens,
+               'video' As materialType
         from (select report.material_id, sum(cost) as totalCost
               from ctop_bytedance_report_material_daily report
                        left join ctop_user_allocation cua on report.account_id = cua.account_id
@@ -126,7 +130,7 @@
                 and report.stat_datetime &lt;= #{endTime}
               group by report.material_id
               order by sum(report.cost) desc ) a
-                 left join (select distinct a.* from ctop_bytedance_video_info a where a.account_id = #{accountId})as video
+                 left join (select distinct a.* from ctop_bytedance_video_info a where a.account_id = #{accountId} and a.type = #{imageMode})as video
                            on a.material_id = video.material_id
                  left join ctop_material_info cmi on cmi.code = video.signature and cmi.project_id = #{projectId}
         where cmi.id = 1
@@ -139,4 +143,120 @@
         order by a.material_id desc
             limit #{videoCnt}
     </select>
+
+
+    <!-- 图片 上新 遗漏 -->
+    <select id="imageListByParams" resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo">
+        select distinct image.*,
+        (select count(1) from ctop_bytedance_ai_video_creative_log l
+        where l.video_code = image.signature
+        and l.account_id = image.account_id
+        and l.state_date = #{now}) as creativeNum,
+        (select count(1) from ctop_bytedance_creative c
+        where SUBSTRING_INDEX(SUBSTRING_INDEX(image_ids,'["',-1),'"]',1) in(image.id)
+        and c.account_id = '${accountId}') as creativeCnt,
+        'image' as materialType
+        from ctop_bytedance_image_info image
+        where account_id = #{accountId}
+        <if test="imageMode == '1'.toString()">
+            and image.type = '1'
+        </if>
+        <if test="imageMode == '2'.toString()">
+            and (image.type = '2' or image.type = '3')
+        </if>
+        <if test="imageMode == '3'.toString()">
+            and image.type = '3'
+        </if>
+        and image.image_create_time &gt;= #{startTime}
+        and image.image_create_time &lt;= #{endTime}
+        having creativeCnt &lt;= #{creativeCnt}
+        and creativeNum = 0
+        order by image.image_create_time desc
+            limit #{videoCnt}
+    </select>
+
+
+    <!-- 图片 跑量-->
+    <select id="imageTopMatByParams" resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo">
+        select distinct image.*,
+        a.totalCost,
+        (select count(1) from ctop_bytedance_ai_video_creative_log l
+        where l.video_code = image.signature
+        and l.account_id = image.account_id
+        and l.state_date =#{now}) as creativeNum,
+        (select count(1)
+        from ctop_bytedance_creative c
+        where SUBSTRING_INDEX(SUBSTRING_INDEX(image_ids,'["',-1),'"]',1) in(image.id)
+        and c.account_id = '${accountId}')  as creativeCnt
+        from (select report.material_id, sum(cost) as totalCost,
+         'image' as materialType
+        from ctop_bytedance_report_image_daily report
+        left join ctop_user_allocation cua on report.account_id = cua.account_id
+        where cua.project_id = #{projectId}
+        and report.stat_datetime &gt;= #{startTime}
+        and report.stat_datetime &lt;= #{endTime}
+        group by report.material_id
+        order by sum(report.cost) desc ) a
+        left join (select distinct a.* from ctop_bytedance_image_info a where 1 = 1  and a.account_id = #{accountId}
+        <if test="imageMode == '1'.toString()">
+            and a.type = '1'
+        </if>
+        <if test="imageMode == '2'.toString()">
+            and (a.type = '2' or a.type = '3')
+        </if>
+        <if test="imageMode == '3'.toString()">
+            and a.type = '3'
+        </if>)as image
+        on a.material_id = image.material_id
+        where 1=1
+        and a.totalCost &gt; 500
+        having creativeCnt &lt;= 100
+        and creativeNum = 0
+        order by a.material_id desc
+            limit #{videoCnt}
+    </select>
+
+
+    <!-- 图片 打捞-->
+    <select id="imageHistoryMatByParams" resultType="org.jeecg.modules.bytedance.advertise.entity.ByteDanceVideoInfo">
+        select distinct image.*,
+        a.totalCost,
+        (select count(1)
+        from ctop_bytedance_ai_video_creative_log l
+        where l.video_code = image.signature
+        and l.account_id = image.account_id
+        and l.state_date = #{now}) as creativeNum,
+        (select count(1)
+        from ctop_bytedance_creative c
+        where SUBSTRING_INDEX(SUBSTRING_INDEX(image_ids,'["',-1),'"]',1) in(image.id)
+        and c.account_id = '${accountId}') as creativeCnt
+        from (select report.material_id, sum(cost) as totalCost,
+        'image' as materialType
+        from ctop_bytedance_report_image_daily report
+        left join ctop_user_allocation cua on report.account_id = cua.account_id
+        where cua.project_id = #{projectId}
+        and report.stat_datetime &gt;= #{startTime}
+        and report.stat_datetime &lt;= #{endTime}
+        group by report.material_id
+        order by sum(report.cost) desc) a
+        left join (select distinct a.* from ctop_bytedance_image_info a where 1 = 1 and a.account_id =#{accountId}
+        <if test="imageMode == '1'.toString()">
+            and a.type = '1'
+        </if>
+        <if test="imageMode == '2'.toString()">
+            and (a.type = '2' or a.type = '3')
+        </if>
+        <if test="imageMode == '3'.toString()">
+            and a.type = '3'
+        </if>) as image
+        on a.material_id = image.material_id
+        where 1=1
+        and a.totalCost &lt;= 100
+        having creativeCnt &lt; 20
+        and creativeNum = 0
+        order by a.material_id desc
+            limit #{videoCnt}
+    </select>
+
+
 </mapper>

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

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.bytedance.advertise.mapper.BytedanceMaterialRejectReasonMapper">
+<insert id="replaceIntoDb" parameterType="org.jeecg.modules.bytedance.advertise.entity.BytedanceMaterialRejectReason">
+    replace into ctop_bytedance_material_reject_reason (reject_reason,image_id,video_id,title,is_low_quality,account_id,ad_id) values (#{rejectReason},#{imageId},#{videoId},#{title},#{isLowQuality},#{accountId},#{adId})
+</insert>
+
+    <select id="getIsLowQualityByVideoId" resultType="integer">
+        select distinct is_low_quality from ctop_bytedance_material_reject_reason where video_id = #{videoId} limit 1
+    </select>
+
+</mapper>

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

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.bytedance.advertise.mapper.BytedancePlanRejectReasonMapper">
+
+<insert id="replaceIntoDb" parameterType="org.jeecg.modules.bytedance.advertise.entity.BytedancePlanRejectReason">
+    replace into ctop_bytedance_plan_reject_reason (ad_id,reject_item,reject_reason,is_low_quality,account_id) values (#{adId},#{rejectItem},#{rejectReason},#{isLowQuality},#{accountId})
+
+</insert>
+</mapper>

+ 16 - 2
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/mapper/xml/BytedanceVideoSlogenInfoMapper.xml

@@ -4,6 +4,8 @@
     <select id="selectVideoSlogenReportByAccountIdAndTitle" resultType="java.util.HashMap">
 
         SELECT
+            a.id,
+            a.status,
             a.slogan,
             a.project_id AS projectId,
             count(*) AS count,
@@ -82,12 +84,13 @@
         AND a.video_code = b.signature
         LEFT JOIN ctop_bytedance_report_creative_daily d ON b.id = d.creative_id
         WHERE
-        a.`status` = 1
+        1=1
+        <if test="status!=null">and a.status = #{status}</if>
         <if test="keyWord!=null and keyWord!=''">and a.slogan like concat('%',#{keyWord},'%')</if>
         <if test="startTime!=null and startTime != ''">and STR_TO_DATE(d.stat_datetime,'%Y-%m-%d') &gt;=
             STR_TO_DATE(#{startTime},'%Y-%m-%d')
         </if>
-        <if test="endTime!=null and endTime != ''">and STR_TO_DATE(d.stat_datetime,'%Y-%m-%d') &lt;=
+        <if test="endTime!=null and endTime!=''">and STR_TO_DATE(d.stat_datetime,'%Y-%m-%d') &lt;=
             STR_TO_DATE(#{endTime},'%Y-%m-%d')
         </if>
         <if test="projectIds!=null">
@@ -113,4 +116,15 @@
             member.user_id = #{userId}
     </select>
 
+
+    <select id="getDataBySlogenAndProjectId" resultType="org.jeecg.modules.bytedance.advertise.entity.BytedanceVideoSlogenInfo">
+    SELECT
+        t1.*,t2.material_name
+    FROM
+        ctop_bytedance_video_slogen_info t1
+    LEFT JOIN ctop_material_info t2 ON t1.video_code = t2.code
+    AND t1.project_id = t2.project_id
+    WHERE
+        slogan =#{slogan} and t1.project_id = #{projectId}
+    </select>
 </mapper>

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

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.jeecg.modules.bytedance.advertise.mapper.LowQualityRejectReasonMapper">
+
+    <select id="getByRejectReason" resultType="org.jeecg.modules.bytedance.advertise.entity.LowQualityRejectReason">
+
+        select * from ctop_low_quality_reject_reason where status = 1 and audit_reject_reason =#{rejectReason}
+    </select>
+</mapper>

+ 19 - 0
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/BytedanceRejectReasonService.java

@@ -0,0 +1,19 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.bytedance.advertise.entity.BytedanceVideoSlogenInfo;
+
+import java.util.List;
+
+/**
+ * 头条视频文案信息
+ * @author jeecg-boot
+ * 2021-04-19
+ * @version V1.0
+ */
+public interface BytedanceRejectReasonService {
+
+     void saveRejectReasonToDb(JSONArray jsonArray,Long accountId);
+}

+ 2 - 2
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IAiBytedanceAdDplinkInfoService.java

@@ -11,7 +11,7 @@ import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAdDplinkInfo;
  */
 public interface IAiBytedanceAdDplinkInfoService extends IService<AiBytedanceAdDplinkInfo> {
 
-    AiBytedanceAdDplinkInfo getlatestDpLinkInfo(Long strategyId, Long accountId, Integer status);
+    AiBytedanceAdDplinkInfo getlatestDpLinkInfo(Long strategyId, Long accountId,String imageMode,Integer status);
 
-    int getDpLinkInfoCount(Long accountId);
+    int getDpLinkInfoCount(Long accountId,String imageMode);
 }

+ 7 - 3
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IAiBytedanceAdvertiserStrategyService.java

@@ -28,14 +28,14 @@ public interface IAiBytedanceAdvertiserStrategyService extends IService<AiByteda
     Result updateADCreative(AiBytedanceAdvertiserStrategy strategy,String groupModifyTime,String planModifyTime);
 
 
-    Long createCreative(AiBytedanceAdvertiserStrategy strategy, Integer createType, Long videoCnt, String openUrl);
+    Long createCreative(CtopOauthToken token, AiBytedanceAdvertiserStrategy strategy, Integer createType, Long videoCnt, String openUrl);
 
     /**
      * 头条 - 配置信息 修改 状态
      * @param
      * @return
      */
-    Result updStaById(String id,String state,String accountId);
+    Result updStaById(String id,String state,String accountId,String creativeImageMode);
 
     /**
      * 头条 - 配置信息 修改 出价; 预算;
@@ -96,7 +96,7 @@ public interface IAiBytedanceAdvertiserStrategyService extends IService<AiByteda
 
     List<AiBytedanceAdvertiserStrategy> getByAccountId(Long accountId,Integer status);
 
-    void customCreativeSupplement(AiBytedanceAdvertiserStrategy strategy, Integer hour,String openUrl);
+    void customCreativeSupplement( AiBytedanceAdvertiserStrategy strategy, Integer hour,String openUrl);
 
     Result getAdActionText(String accountId,String landingType,String advancedCreativeType) throws Exception;
 
@@ -114,6 +114,10 @@ public interface IAiBytedanceAdvertiserStrategyService extends IService<AiByteda
     Result getChengZiSite(String accountId);
 
 
+    /**
+     * 查询 组名称 计划名称
+     */
+    Result getStrategyInfoByName(AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy);
 
 
 }

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

@@ -0,0 +1,14 @@
+package org.jeecg.modules.bytedance.advertise.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAutocreateLog;
+
+/**
+ * 自动创建计划日志
+ * @author jeecg-boot
+ * 2021-07-05
+ * @version V1.0
+ */
+public interface IAiBytedanceAutocreateLogService extends IService<AiBytedanceAutocreateLog> {
+
+}

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

@@ -37,6 +37,8 @@ public interface IByteDanceAdvertisePlanService extends IService<ByteDanceAdvert
 
     List<ByteDanceAdvertisePlan> getAllPlans(Long accountId,String createDate);
 
+    List<ByteDanceAdvertisePlan> getAllPlansByAccountId(Long accountId,String adModifyTime);
+
     int queryToDayBuiltCount(Long accountId);
 
     Integer updatePlanOrPackage (ByteDanceAdvertisePlan byteDanceAdvertisePlan);

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

@@ -19,7 +19,6 @@ public interface IByteDanceCreativeService extends IService<ByteDanceCreative> {
 
     Map<String, Object> getAdvertiserCreative(CtopOauthToken token, String ids, String date);
 
-
     void replaceBatch(List<ByteDanceCreative> creatives);
 
     Map<String, Object> getCreativeDetail(CtopOauthToken token, Long planId);

+ 5 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceGeneralCopywriterService.java

@@ -5,6 +5,8 @@ import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreativeWordPackage;
 import org.jeecg.modules.bytedance.advertise.entity.ByteDanceGeneralCopywriter;
 
+import java.util.List;
+
 /**
  * 通用文案库
  * @author jeecg-boot
@@ -12,7 +14,9 @@ import org.jeecg.modules.bytedance.advertise.entity.ByteDanceGeneralCopywriter;
  * @version V1.0
  */
 public interface IByteDanceGeneralCopywriterService extends IService<ByteDanceGeneralCopywriter> {
-    Result getGeneralCopywriterReport(String userId, String accountId, String keyWord, String startTime, String endTime, Integer pageNum, Integer pageSize);
+    Result getGeneralCopywriterReport(String userId, String accountId, String keyWord,Integer status, String startTime, String endTime, Integer pageNum, Integer pageSize);
 
     public ByteDanceCreativeWordPackage selectCreativeWordPackageByName(String name);
+
+    List<ByteDanceGeneralCopywriter> selectAllDataByTextCopywriter(String textCopywriter);
 }

+ 26 - 3
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IByteDanceVideoInfoService.java

@@ -19,9 +19,32 @@ public interface IByteDanceVideoInfoService extends IService<ByteDanceVideoInfo>
 
     void updateMaterialType();
 
-    List<ByteDanceVideoInfo> listByParams(Long projectId,Long accountId, String startTime, String endTime, Long videoCnt,long creativeCnt);
+    List<ByteDanceVideoInfo> listByParams(Long projectId,Long accountId, String imageMode,String startTime, String endTime, Long videoCnt,long creativeCnt);
+
+    List<ByteDanceVideoInfo> topMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt);
+
+    List<ByteDanceVideoInfo> historyMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt);
+
+
+    /**
+     * 图片 上新 遗漏
+     */
+    List<ByteDanceVideoInfo> imageListByParams(Long projectId,Long accountId, String imageMode,String startTime, String endTime, Long videoCnt,long creativeCnt);
+
+    /**
+     * 图片 跑量
+     */
+    List<ByteDanceVideoInfo> imageTopMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt);
+
+    /**
+     * 图片 打捞
+     */
+    List<ByteDanceVideoInfo> imageHistoryMatByParams(Long projectId, Long accountId,String imageMode, String startTime, String endTime, Long videoCnt);
+
+
+
+
+
 
-    List<ByteDanceVideoInfo> topMatByParams(Long projectId, Long accountId, String startTime, String endTime, Long videoCnt);
 
-    List<ByteDanceVideoInfo> historyMatByParams(Long projectId, Long accountId, String startTime, String endTime, Long videoCnt);
 }

+ 3 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/IBytedanceVideoSlogenInfoService.java

@@ -19,5 +19,7 @@ public interface IBytedanceVideoSlogenInfoService extends IService<BytedanceVide
 
     List<BytedanceVideoSlogenInfo> listByParams(String code, Integer status);
 
-    Result getVideoSlogenReport(String userId, String projectId,String keyWord, String startTime, String endTime, Integer pageNum, Integer pageSize);
+    Result getVideoSlogenReport(String userId, String projectId,String keyWord,Integer status, String startTime, String endTime, Integer pageNum, Integer pageSize);
+
+    List<BytedanceVideoSlogenInfo> getVideoSlogenBySlogenAndProjectId(String slogen, Long projectId);
 }

+ 6 - 2
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/AiBytedanceAdDplinkInfoServiceImpl.java

@@ -24,7 +24,7 @@ public class AiBytedanceAdDplinkInfoServiceImpl extends ServiceImpl<AiBytedanceA
     private AiBytedanceAdDplinkInfoMapper aiBytedanceAdDplinkInfoMapper;
 
     @Override
-    public AiBytedanceAdDplinkInfo getlatestDpLinkInfo(Long strategyId, Long accountId, Integer status) {
+    public AiBytedanceAdDplinkInfo getlatestDpLinkInfo(Long strategyId, Long accountId, String imageMode,Integer status) {
         QueryWrapper<AiBytedanceAdDplinkInfo> queryWrapper = new QueryWrapper<>();
         if(null!=strategyId&&strategyId!=0){
             queryWrapper.eq("strategy_id",strategyId);
@@ -35,6 +35,9 @@ public class AiBytedanceAdDplinkInfoServiceImpl extends ServiceImpl<AiBytedanceA
         if(null!=status){
             queryWrapper.eq("status",status);
         }
+        if(null!=imageMode){
+            queryWrapper.eq("image_mode",imageMode);
+        }
         queryWrapper.orderByDesc("id").last("limit 1");
         return this.getOne(queryWrapper);
     }
@@ -48,13 +51,14 @@ public class AiBytedanceAdDplinkInfoServiceImpl extends ServiceImpl<AiBytedanceA
      * @author: zianY
      */
     @Override
-    public int getDpLinkInfoCount(Long accountId) {
+    public int getDpLinkInfoCount(Long accountId,String imageMode) {
         QueryWrapper<AiBytedanceAdDplinkInfo> queryWrapper = new QueryWrapper<>();
         Date date = new Date();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
         String format = sdf.format(date);
         queryWrapper.eq("account_id",accountId);
         queryWrapper.ge("create_time",format);
+        queryWrapper.eq("image_mode",imageMode);
         return aiBytedanceAdDplinkInfoMapper.selectCount(queryWrapper);
 
     }

+ 306 - 69
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/AiBytedanceAdvertiserStrategyServiceImpl.java

@@ -12,10 +12,7 @@ import org.jeecg.common.util.DateUtils;
 import org.jeecg.modules.bytedance.advertise.dockapi.MarketingService;
 import org.jeecg.modules.bytedance.advertise.entity.*;
 import org.jeecg.modules.bytedance.advertise.enums.BytedanceCreativeMatTypeEnum;
-import org.jeecg.modules.bytedance.advertise.mapper.AiBytedanceAdvertiserStrategyMapper;
-import org.jeecg.modules.bytedance.advertise.mapper.ByteDanceGeneralCopywriterMapper;
-import org.jeecg.modules.bytedance.advertise.mapper.BytedanceAreaInfoMapper;
-import org.jeecg.modules.bytedance.advertise.mapper.RuleDataAccountMapper;
+import org.jeecg.modules.bytedance.advertise.mapper.*;
 import org.jeecg.modules.bytedance.advertise.service.*;
 import org.jeecg.modules.bytedance.advertise.vo.AdConvertQueryVo;
 import org.jeecg.modules.bytedance.advertise.vo.AdGroupSearchVo;
@@ -38,6 +35,7 @@ import javax.transaction.Transactional;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
+import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAutocreateLog;
 
 /**
  * 头条智能投放账户配置信息表
@@ -76,17 +74,25 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
     private MarketingService marketingService;
     @Resource
     ByteDanceGeneralCopywriterMapper byteDanceGeneralCopywriterMapper;
+    @Resource
+    BytedanceMaterialRejectReasonMapper bytedanceMaterialRejectReasonMapper;
+    @Autowired
+    IAiBytedanceAutocreateLogService iBytedanceAutocreateLogService;
+
     @Override
-    public Long createCreative(AiBytedanceAdvertiserStrategy strategy, Integer createType, Long videoCnt, String openUrl) {
-        CtopOauthToken token = tokenService.getOauthTokenByAccountId(strategy.getAccountId()+"");
-        if (null == token) {
-            log.info("token获取失败=>accountId:{}", strategy.getAccountId());
-            return videoCnt;
-        }
+    public Long createCreative(CtopOauthToken token, AiBytedanceAdvertiserStrategy strategy, Integer createType, Long videoCnt, String openUrl) {
+
 
         UserAllocation userAllocation = userAllocationService.getByAccountId(strategy.getAccountId());
         if(null == userAllocation||userAllocation.getAccountStatus()!=0){
             log.info("此账户不存在或者已经被关闭=>accountId:{}", token.getAccountId());
+            AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                    token.getAccountId(),
+                    "获取账户",
+                    500,
+                    "此账户不存在或者已经被关闭=>accountId:" + token.getAccountId(),
+                    "userAllocationService.getByAccountId => "+ token.getAccountId());
+            iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
             return videoCnt;
         }
         //获取全量广告组数据
@@ -103,17 +109,35 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         if(timeEnd != 0){
             endTime = DateUtils.formatDateTime(now + timeEnd * 60 * 1000L);
         }
-        List<ByteDanceVideoInfo> videoInfos = getVideoInfoByCreateType(userAllocation.getProjectId(),strategy,startTime,endTime,createType,videoCnt);
+        //List<ByteDanceVideoInfo> videoInfos = getVideoInfoByCreateType(userAllocation.getProjectId(),strategy,startTime,endTime,createType,videoCnt);
+        List<ByteDanceVideoInfo> videoInfos = getvideoOrImageInfoByCreateType(userAllocation.getProjectId(),strategy,startTime,endTime,createType,videoCnt);
         if(null == videoInfos||videoInfos.isEmpty()){
             log.info("获取{}视频素材为空=>accountId:{}",BytedanceCreativeMatTypeEnum.getNameByType(createType+""),token.getAccountId());
             return videoCnt;
         }
-        log.info("获取{}视频素材个数:{}=>accountId:{}",BytedanceCreativeMatTypeEnum.getNameByType(createType+""),videoInfos.size(),token.getAccountId());
+        log.info("获取{}素材个数:{}=>accountId:{}",BytedanceCreativeMatTypeEnum.getNameByType(createType+""),videoInfos.size(),token.getAccountId());
+        AiBytedanceAutocreateLog iBytedanceAutocreateLogofVideoInfo = new AiBytedanceAutocreateLog(
+                token.getAccountId(),
+                "获取素材",
+                200,
+                "获取"+BytedanceCreativeMatTypeEnum.getNameByType(createType+"")+"素材个数"+videoInfos.size(),
+                "");
+        iBytedanceAutocreateLogService.save(iBytedanceAutocreateLogofVideoInfo);
 
         for (ByteDanceVideoInfo video:videoInfos) {
+            //判断此素材为视频
+            if ("video".equalsIgnoreCase(video.getMaterialType())){
+                //视频是否是低质视频,为1跳过
+                Integer isLowQuality = bytedanceMaterialRejectReasonMapper.getIsLowQualityByVideoId(video.getVid());
+                if(!Check.isNull(isLowQuality) && 1 == isLowQuality){
+                    continue;
+                }
+            }
+
             Integer useDplinkIndex = strategy.getDpLinkIndexUsed();
             if(null==useDplinkIndex||useDplinkIndex.equals(0)){
-                AiBytedanceAdDplinkInfo adDplinkInfo = adDplinkInfoService.getlatestDpLinkInfo(strategy.getId(),strategy.getAccountId(),1);
+                //查看已使用的dp链接
+                AiBytedanceAdDplinkInfo adDplinkInfo = adDplinkInfoService.getlatestDpLinkInfo(strategy.getId(),strategy.getAccountId(),strategy.getCreativeImageMode(),1);
                 if(null == adDplinkInfo){
                     adDplinkInfo = new AiBytedanceAdDplinkInfo();
                     if("FIX".equalsIgnoreCase(strategy.getAdBidCreateType())){
@@ -137,7 +161,7 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                     return videoCnt;
                 }
                 //计划名称
-                String adName = getAdName(strategy,null,video);
+                String adName = getAdName(strategy,null,video,userAllocation.getProjectId());
                 //计算本次出价
                 BigDecimal currentCpaBid = StringUtils.getRandomAdCpaBid(strategy.getAdBidCreateType(),strategy.getAdMaxBid(),strategy.getAdMinBid(),strategy.getAdStepBid(),adDplinkInfo.getAdBid(),strategy.getAdCpaBid());
                 JSONObject adParams = getAdParams(strategy,adName,campaignId,currentCpaBid);
@@ -156,12 +180,26 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                     Result resultDeletePlan = marketingService.updPlanStatus(token,adIds,"delete");
                     if (!resultDeletePlan.isSuccess()){
                         log.info("广告计划删除失败:message==>{}",resultDeletePlan.getMessage());
+                        AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                                token.getAccountId(),
+                                "广告计划删除失败",
+                                resultDeletePlan.getCode(),
+                                resultDeletePlan.getMessage(),
+                                "marketingService.updPlanStatus => token:"+ token.toString()+",adIds:"+adIds.toString()+",optstatus:delete");
+                        iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
                     }
 
                     String message = creativeObject.getString("message");
                     Integer code = creativeObject.getInteger("code");
                     //创建创意失败
                     log.info("账户id:{};创意创建失败:code==>{};message==>{}",strategy.getAccountId(),code,message);
+                    AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                            strategy.getAccountId(),
+                            "创意创建失败",
+                            code,
+                            message,
+                            "marketingService.creativeCreate => token:"+ token.toString()+",adIds:"+adIds.toString()+",creativeParams:"+creativeParams.toJSONString());
+                    iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
                     continue;
                 }
 
@@ -169,6 +207,7 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                 adDplinkInfo.setAccountId(strategy.getAccountId());
                 adDplinkInfo.setStatus(1);
                 adDplinkInfo.setStrategyId(strategy.getId());
+                adDplinkInfo.setImageMode(strategy.getCreativeImageMode());
                 adDplinkInfoService.save(adDplinkInfo);
 
                 BytedanceAiVideoCreativeLog creativeLog = new BytedanceAiVideoCreativeLog(strategy,adId,campaignId,video);
@@ -179,7 +218,7 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                 }
             }else{
                 Long dpIndex ;
-                AiBytedanceAdDplinkInfo adDplinkInfo = adDplinkInfoService.getlatestDpLinkInfo(strategy.getId(),strategy.getAccountId(),1);
+                AiBytedanceAdDplinkInfo adDplinkInfo = adDplinkInfoService.getlatestDpLinkInfo(strategy.getId(),strategy.getAccountId(),strategy.getCreativeImageMode(),1);
                 if(null == adDplinkInfo){
                     adDplinkInfo = new AiBytedanceAdDplinkInfo();
                     if("FIX".equalsIgnoreCase(strategy.getAdBidCreateType())){
@@ -193,9 +232,18 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                     adDplinkInfo.setDpLinkIndex(adDplinkInfo.getDpLinkIndex()+1);
                 }
                 dpIndex = adDplinkInfo.getDpLinkIndex();
-                // 已创建计划 > 账户配置结束下标
-                if(dpIndex>strategy.getDpLinkEndIndex()){
-                    log.info("此账户策略创建结束=>账户id:{};策略id:{}", token.getAccountId(),strategy.getId());
+                // 超出下标范围
+                // 已使用dp链接 < 账户配置结束下标 || 已使用dp链接 > 结束下标
+                if( dpIndex < strategy.getDpLinkStartIndex() || dpIndex > strategy.getDpLinkEndIndex()){
+                    log.info("此账户策略创建结束===已创建dp链接超过了限制===>账户id:{};策略id:{}", token.getAccountId(),strategy.getId());
+                    AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                            token.getAccountId(),
+                            "策略创建结束",
+                            500,
+                            "已创建dp链接超过了限制",
+                            "token:"+ token.toString()+",策略id:"+strategy.getId()+
+                                    dpIndex+"<" + strategy.getDpLinkStartIndex() +"||" +dpIndex +">" + strategy.getDpLinkEndIndex());
+                    iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
                     return 0L;
                 }
                 //组名称
@@ -208,7 +256,7 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                 strategy.setAdOpenUrl(openUrl.replace("{{dp链接下标}}",dpIndex.toString()));
                 String dplinkCode = StringUtils.getParamFromUrl(strategy.getAdOpenUrl(),"bc_fl_src");
                 //计划名称
-                String adName = getAdName(strategy,dplinkCode,video);
+                String adName = getAdName(strategy,dplinkCode,video,userAllocation.getProjectId());
                 //计算本次出价
                 BigDecimal currentCpaBid = StringUtils.getRandomAdCpaBid(strategy.getAdBidCreateType(),strategy.getAdMaxBid(),strategy.getAdMinBid(),strategy.getAdStepBid(),adDplinkInfo.getAdBid(),strategy.getAdCpaBid());
                 adDplinkInfo.setAdBid(currentCpaBid);
@@ -228,11 +276,25 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                     Result resultDeletePlan = marketingService.updPlanStatus(token,adIds,"delete");
                     if (!resultDeletePlan.isSuccess()){
                         log.info("广告计划删除失败:message==>{}",resultDeletePlan.getMessage());
+                        AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                                token.getAccountId(),
+                                "广告计划删除失败",
+                                resultDeletePlan.getCode(),
+                                resultDeletePlan.getMessage(),
+                                "marketingService.updPlanStatus => token:"+ token.toString()+",adIds:"+adIds.toString()+",optstatus:delete");
+                        iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
                     }
                     String message = creativeObject.getString("message");
                     Integer code = creativeObject.getInteger("code");
                     //创建创意失败
                     log.info("账户id:{};创意创建失败:code==>{};message==>{}",strategy.getAccountId(),code,message);
+                    AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                            strategy.getAccountId(),
+                            "创意创建失败",
+                            code,
+                            message,
+                            "marketingService.creativeCreate => token:"+ token.toString()+",adIds:"+adIds.toString()+",creativeParams:"+creativeParams.toJSONString());
+                    iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
                     continue;
                 }
 
@@ -240,9 +302,13 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                 adDplinkInfo.setAccountId(strategy.getAccountId());
                 adDplinkInfo.setStatus(1);
                 adDplinkInfo.setStrategyId(strategy.getId());
+                adDplinkInfo.setImageMode(strategy.getCreativeImageMode());
                 adDplinkInfoService.save(adDplinkInfo);
                 BytedanceAiVideoCreativeLog creativeLog = new BytedanceAiVideoCreativeLog(strategy,adId,campaignId,video);
                 videoCreativeLogService.saveOrUpdate(creativeLog);
+
+
+
                 videoCnt --;
                 if(videoCnt<=0){
                     return 0L;
@@ -253,15 +319,20 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
     }
     private JSONObject getCreativeParams(AiBytedanceAdvertiserStrategy strategy, Long adId,ByteDanceVideoInfo videoInfo,CtopOauthToken token) {
         JSONObject params = new JSONObject();
-        params.put("advertiser_id",strategy.getAccountId());
-        params.put("ad_id",adId);
+        params.put("advertiser_id", strategy.getAccountId());
+        params.put("ad_id", adId);
         String inventoryType = strategy.getCreativeInventoryType();
-        if(null!=inventoryType&&!"".equals(inventoryType)){
+        if ("CREATIVE_IMAGE_MODE_UNION_SPLASH".equalsIgnoreCase(strategy.getCreativeImageMode())) {
+            params.put("inventory_type", new String[]{"INVENTORY_UNION_SPLASH_SLOT"});
+        } else {
+        if (null != inventoryType && !"".equals(inventoryType)) {
             String[] inventoryTypeString = inventoryType.split(",");
-            if(inventoryTypeString.length>0){
-              params.put("inventory_type",inventoryTypeString);
+            if (inventoryTypeString.length > 0) {
+                params.put("inventory_type", inventoryTypeString);
             }
         }
+    }
+
         Integer smartInventory = strategy.getCreativeSmartInventory();
         if(null!=smartInventory&&smartInventory!=0){
             params.put("smart_inventory",smartInventory);
@@ -286,25 +357,32 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         //视频素材
         JSONArray imageArray = new JSONArray();
         JSONObject imageObject = new JSONObject();
-        //视频类型
-        if(videoInfo.getType() == 1){
-            //竖版视频
-            imageObject.put("image_mode","CREATIVE_IMAGE_MODE_VIDEO_VERTICAL");
-        }
-        if(videoInfo.getType() == 2){
-            //横版视频
-            imageObject.put("image_mode","CREATIVE_IMAGE_MODE_VIDEO");
-        }
-        imageObject.put("video_id",videoInfo.getVid());
-        //获取视频封面id
-        String imageId = getSuggestImageId(token,videoInfo.getVid());
-        if(!Check.isNull(imageId)){
-            imageObject.put("image_id",imageId);
+
+        if ("video".equalsIgnoreCase(videoInfo.getMaterialType())){
+            //视频类型
+            //1-竖版视频 2-横版视频
+//            String imageMode = videoInfo.getType() == 1 ? "CREATIVE_IMAGE_MODE_VIDEO_VERTICAL" : "CREATIVE_IMAGE_MODE_VIDEO";
+            String imageMode = strategy.getCreativeImageMode();
+            imageObject.put("image_mode",imageMode);
+            imageObject.put("video_id",videoInfo.getVid());
+            //获取视频封面id
+            String imageId = getSuggestImageId(token,videoInfo.getVid());
+            if(!Check.isNull(imageId)){
+                imageObject.put("image_id",imageId);
+            }
+        }else if ("image".equalsIgnoreCase(videoInfo.getMaterialType())){
+            //1-大图横图; 2-大图竖图
+//            String imageMode = videoInfo.getType() == 1 ? "CREATIVE_IMAGE_MODE_LARGE" : "CREATIVE_IMAGE_MODE_LARGE_VERTICAL";
+            String imageMode = strategy.getCreativeImageMode();
+            imageObject.put("image_mode",imageMode);
+            imageObject.put("image_ids",new String[]{videoInfo.getId()});
         }
+
         imageArray.add(imageObject);
         params.put("image_list",imageArray);
         JSONArray titleArray = new JSONArray();
         List<BytedanceVideoSlogenInfo> slogenInfos = slogenInfoService.listByParams(videoInfo.getSignature(),1);
+        //使用指定文案
         if(!Check.isNull(slogenInfos)){
             for (BytedanceVideoSlogenInfo slogenInfo:slogenInfos) {
                 if(titleArray.size() >= 10){    //接口中是要求一个视频最多10个标题
@@ -321,12 +399,33 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                 }
                 titleArray.add(titleObject);
             }
-            for(int i = 0; i < 3; i++){
-                if(titleArray.size() >= 10){
-                    break;
+        }
+
+        // 视频 指定文案不够的时候 使用通用文案 最多3条
+        if ("video".equalsIgnoreCase(videoInfo.getMaterialType())){
+            List<ByteDanceGeneralCopywriter> byteDanceGeneralCopywriter = byteDanceGeneralCopywriterMapper.getRandThree(strategy.getAccountId());
+            if(!Check.isNull(byteDanceGeneralCopywriter)){
+                for(int i = 0; i < byteDanceGeneralCopywriter.size(); i++){
+                    if(titleArray.size() >= 10){
+                        break;
+                    }
+                    JSONObject titleObject = new JSONObject();
+                    titleObject.put("title",byteDanceGeneralCopywriter.get(i).getTextCopywriter());
+                    String creativeWordsIds = byteDanceGeneralCopywriter.get(i).getCreativeWordIds();
+                    if(null!=creativeWordsIds&&!creativeWordsIds.trim().equals("")){
+                        JSONArray creativeWordsArray = JSON.parseArray(creativeWordsIds);
+                        if(null!=creativeWordsArray&&!creativeWordsArray.isEmpty()){
+                            titleObject.put("creative_word_ids",creativeWordsArray);
+                        }
+                    }
+                    titleArray.add(titleObject);
                 }
-                ByteDanceGeneralCopywriter byteDanceGeneralCopywriter = byteDanceGeneralCopywriterMapper.getRandOne(strategy.getAccountId());
-                if(!Check.isNull(byteDanceGeneralCopywriter)){
+            }
+            // 图片 使用通用文案 最多10条
+        }else if ("image".equalsIgnoreCase(videoInfo.getMaterialType())){
+            List<ByteDanceGeneralCopywriter> byteDanceGeneralCopywriterList = byteDanceGeneralCopywriterMapper.getRandTen(strategy.getAccountId());
+            if(!Check.isNull(byteDanceGeneralCopywriterList)){
+                for (ByteDanceGeneralCopywriter byteDanceGeneralCopywriter : byteDanceGeneralCopywriterList){
                     JSONObject titleObject = new JSONObject();
                     titleObject.put("title",byteDanceGeneralCopywriter.getTextCopywriter());
                     String creativeWordsIds = byteDanceGeneralCopywriter.getCreativeWordIds();
@@ -338,10 +437,9 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
                     }
                     titleArray.add(titleObject);
                 }
-
             }
-
         }
+
         if(!Check.isNull(titleArray)){
             params.put("title_list",titleArray);
         }
@@ -513,7 +611,13 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         Result result = marketingService.createAdvertiserPlan(token,adParams,strategy);
         System.out.println(result);
         if(result.getCode()!=0){
-            //TODO 计划创建异常 后续需要加日志
+            AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                    strategy.getAccountId(),
+                    "计划创建异常",
+                    result.getCode(),
+                    result.getMessage(),
+                    adParams.toJSONString());
+            iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
             return null;
         }
         return (Long)result.getResult();
@@ -909,7 +1013,7 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         return params;
     }
 
-    private String getAdName(AiBytedanceAdvertiserStrategy strategy, String dplinkCode, ByteDanceVideoInfo videoInfo) {
+    private String getAdName(AiBytedanceAdvertiserStrategy strategy, String dplinkCode, ByteDanceVideoInfo videoInfo,Long projectId) {
         String adName = strategy.getAdName();
         if(null == adName|| "".equals(adName.trim())){
             return null;
@@ -928,14 +1032,20 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
             String pricing = strategy.getAdPricing().replace("PRICING_","").toLowerCase(Locale.ROOT);
             adName = adName.replace("{{出价方式}}",pricing);
         }
+
         if(adName.contains("{{素材名称}}")){
-            MaterialInfo info = materialInfoService.getParams(videoInfo.getSignature(),null);
-            if(null!=info&&null!=info.getMaterialName()){
-                adName = adName.replace("{{素材名称}}",info.getMaterialName());
+            if ("video".equals(videoInfo.getMaterialType())){
+                MaterialInfo info = materialInfoService.getParams(videoInfo.getSignature(),null,projectId);
+                if(null!=info&&null!=info.getMaterialName()){
+                    adName = adName.replace("{{素材名称}}",info.getMaterialName());
+                }
+            }else {
+                adName = adName.replace("{{素材名称}}",videoInfo.getFilename());
             }
         }
+
         if(adName.contains("{{序号}}")){
-            int i = adDplinkInfoService.getDpLinkInfoCount(strategy.getAccountId());
+            int i = adDplinkInfoService.getDpLinkInfoCount(strategy.getAccountId(),strategy.getCreativeImageMode());
             adName = adName.replace("{{序号}}",String.valueOf(i+1));
         }
 
@@ -985,7 +1095,13 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         //创建组
         Result campaignData = marketingService.createCampaign(token, campaignParam);
         if(campaignData.getCode()!=0){
-            //TODO 组创建异常 后续需要加日志
+            AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                    strategy.getAccountId(),
+                    "组创建异常",
+                    campaignData.getCode(),
+                    campaignData.getMessage(),
+                    campaignParam.toJSONString());
+            iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
             return null;
         }
         return (Long)campaignData.getResult();
@@ -1002,9 +1118,9 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         }
 
         if(result.contains("{{序号}}")){
-            //查询当天已有计划数量
-            int i = adDplinkInfoService.getDpLinkInfoCount(strategy.getAccountId());
-            Long num = GetCampaignNum.getCampaignNameNum(strategy.getCampaignCnt(),strategy.getCampaignAdCnt(), i == 0 ? i+1 : i);
+            //查询同素材类型当天已有计划数量
+            int i = adDplinkInfoService.getDpLinkInfoCount(strategy.getAccountId(),strategy.getCreativeImageMode());
+            Long num = GetCampaignNum.getCampaignNameNum(strategy.getCampaignCnt(),strategy.getCampaignAdCnt(), i+1);
             result = result.replace("{{序号}}",String.valueOf(num));
         }
 
@@ -1025,10 +1141,10 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
     }
 
     private String getRangeIndex(Long dpLinkStartIndex,Long dpLinkEndIndex, Long campaignAdCnt, Long dpIndex) {
-        if(dpIndex<dpLinkStartIndex||dpIndex>dpLinkEndIndex){
+       /* if(dpIndex<dpLinkStartIndex||dpIndex>dpLinkEndIndex){
             //超出下标范围
             return null;
-        }
+        }*/
         Long startIndex ;
         Long endIndex ;
         //计算当前下标值和范围区段的余数
@@ -1040,24 +1156,71 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
             startIndex = dpIndex-yzIndex+1;
             endIndex = dpIndex-yzIndex+campaignAdCnt;
         }
+        //dp 链接 超出可用范围
+        if (endIndex > dpLinkEndIndex){
+            endIndex = dpLinkEndIndex;
+        }
         return "-("+startIndex+"/"+endIndex+")";
     }
 
     //TODO -- 高质量素材 一天只能创建一次 两周内总消耗》=500
     //TODO -- 打捞素材  两周消耗 <500 并且总关联创意数<20
     private List<ByteDanceVideoInfo> getVideoInfoByCreateType(Long projectId,AiBytedanceAdvertiserStrategy strategy, String startTime, String endTime, Integer createType, Long videoCnt) {
+        //根据 imageMode 获取素材类型
+        //1-竖版视频 2-横板视频
+        String imageMode = BytedanceCreativeMatTypeEnum.getNameByType(strategy.getCreativeImageMode());
         //1:上新素材 2:跑量素材 3:遗漏素材 4:打捞素材
         if(createType == 1||createType == 3){
-            return videoInfoService.listByParams(projectId,strategy.getAccountId(),startTime,endTime,videoCnt,0);
+            return videoInfoService.listByParams(projectId,strategy.getAccountId(),imageMode,startTime,endTime,videoCnt,0);
         }else if(createType == 2){
             startTime = startTime.substring(0,10);
             endTime = endTime.substring(0,10);
-            return videoInfoService.topMatByParams(projectId,strategy.getAccountId(),startTime,endTime,videoCnt);
+            return videoInfoService.topMatByParams(projectId,strategy.getAccountId(),imageMode,startTime,endTime,videoCnt);
+        }else if(createType == 4){
+            return videoInfoService.historyMatByParams(projectId,strategy.getAccountId(),imageMode,startTime,endTime,videoCnt);
+        }
+        return null;
+    }
+
+    /**
+     * 图片素材
+     */
+    private List<ByteDanceVideoInfo> getImageInfoByCreateType(Long projectId,AiBytedanceAdvertiserStrategy strategy, String startTime, String endTime, Integer createType, Long videoCnt) {
+        //根据 imageMode 获取素材类型
+        //1-大图横图; 2-大图竖图 3-开屏
+        String imageMode = BytedanceCreativeMatTypeEnum.getNameByType(strategy.getCreativeImageMode());
+        //1:上新素材 2:跑量素材 3:遗漏素材 4:打捞素材
+        if(createType == 1||createType == 3){
+            return videoInfoService.imageListByParams(projectId,strategy.getAccountId(),imageMode,startTime,endTime,videoCnt,0);
+        }else if(createType == 2){
+            return videoInfoService.imageTopMatByParams(projectId,strategy.getAccountId(),imageMode,startTime,endTime,videoCnt);
         }else if(createType == 4){
-            return videoInfoService.listByParams(projectId,strategy.getAccountId(),startTime,endTime,videoCnt,20);
+            return videoInfoService.imageHistoryMatByParams(projectId,strategy.getAccountId(),imageMode,startTime,endTime,videoCnt);
         }
         return null;
     }
+
+    private List<ByteDanceVideoInfo> getvideoOrImageInfoByCreateType(Long projectId,AiBytedanceAdvertiserStrategy strategy, String startTime, String endTime, Integer createType, Long videoCnt) {
+        //横板视频 || 竖版视频
+        if (strategy.getCreativeImageMode().equalsIgnoreCase("CREATIVE_IMAGE_MODE_VIDEO")
+                || strategy.getCreativeImageMode().equalsIgnoreCase("CREATIVE_IMAGE_MODE_VIDEO_VERTICAL")){
+            //获取 视频 素材
+            return getVideoInfoByCreateType(projectId,strategy,startTime,endTime,createType,videoCnt);
+        }
+        //获取 图片 素材
+        return getImageInfoByCreateType(projectId,strategy,startTime,endTime,createType,videoCnt);
+    }
+
+
+
+
+
+
+
+
+
+
+
     /**
      *  修改状态 (0开-1关)
      *  同一账户下只能有一条数据信息为开启,可以全部关闭
@@ -1066,13 +1229,13 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
      */
     @Override
     @Transactional
-    public Result updStaById(String id,String state,String accountId) {
+    public Result updStaById(String id,String state,String accountId,String creativeImageMode) {
         //开启
         if (org.apache.commons.lang3.StringUtils.equals(state,"0")){
             //修改状态为开启
             aiBytedanceAdvertiserStrategyMapper.updStaById(id,state);
             //关闭 账户下 其他数据信息(不包含本条id信息) 状态为 关闭
-            aiBytedanceAdvertiserStrategyMapper.updStaByAccountId(accountId,"1",id);
+            aiBytedanceAdvertiserStrategyMapper.updStaByAccountId(accountId,creativeImageMode,"1",id);
         }
         //关闭
         if (org.apache.commons.lang3.StringUtils.equals(state,"1")){
@@ -1376,9 +1539,9 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         //默认组数量为 1 -前端已修改完成
         //aiBytedanceAdvertiserStrategy.setCampaignAdCnt(aiBytedanceAdvertiserStrategy.getCampaignAdCnt() == 0L ? 1 : aiBytedanceAdvertiserStrategy.getCampaignAdCnt());
 
-        //同一账户下 只能有一条信息为开启
+        //同一账户下 同素材类型 只能有一条信息为开启
         //关闭 账户下 其他数据信息(不包含本条id信息) 状态为 关闭
-        aiBytedanceAdvertiserStrategyMapper.updStaByAccountId(String.valueOf(aiBytedanceAdvertiserStrategy.getAccountId()),"1",null);
+        aiBytedanceAdvertiserStrategyMapper.updStaByAccountId(String.valueOf(aiBytedanceAdvertiserStrategy.getAccountId()),aiBytedanceAdvertiserStrategy.getCreativeImageMode(),"1",null);
         //状态(0开 1关)
         aiBytedanceAdvertiserStrategy.setStatus(0);
 
@@ -1388,6 +1551,8 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         imageInfo.setUserId(aiBytedanceAdvertiserStrategy.getUserId());
         materialImageInfoService.initImageCode(imageInfo);
 
+
+
         aiBytedanceAdvertiserStrategyMapper.insert(aiBytedanceAdvertiserStrategy);
 
 
@@ -1417,36 +1582,63 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
 
     @Autowired
     private IByteDanceAdvertisePlanService planService;
+    @Autowired
+    private IByteDanceAdvertiserDataService advertiserDataService;
+
     @Override
     public void customCreativeSupplement(AiBytedanceAdvertiserStrategy strategy, Integer hour,String openUrl) {
         try{
+            CtopOauthToken token = tokenService.getOauthTokenByAccountId(strategy.getAccountId()+"");
+            if (null == token) {
+                log.info("token获取失败=>accountId:{}", strategy.getAccountId());
+                AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                        strategy.getAccountId(),
+                        "获取token",
+                        500,
+                        "token获取失败=>accountId:" + strategy.getAccountId(),
+                        "tokenService.getOauthTokenByAccountId => "+ strategy.getAccountId());
+                iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
+                return;
+            }
             Long customUnitCnt = strategy.getCampaignAdCnt()*strategy.getCampaignCnt();
             Long unitNum = customUnitCnt * hour / 19;
             log.info("{}当前时间内需要创建计划总数:{}", strategy.getAccountId(), unitNum);
             //查询当前账户创建自定义类型计划数量
             int unitCreateCnt = planService.queryToDayBuiltCount(strategy.getAccountId());
-            log.info("{}截止目前创建组总数:{}", strategy.getAccountId(), unitCreateCnt);
+            log.info("{}截止目前创建计划总数:{}", strategy.getAccountId(), unitCreateCnt);
             long remindCnt = unitNum - unitCreateCnt;
             if (remindCnt >= 1) {
                 log.info("{}计划创建不足,剩余需要创建个数{},使用上新素材创建", strategy.getAccountId(), remindCnt);
                 //优先创建历史遗漏素材
-                remindCnt = this.createCreative(strategy, 1, remindCnt,openUrl);
+                remindCnt = this.createCreative(token, strategy, 1, remindCnt,openUrl);
             }
             if (remindCnt >= 1) {
                 log.info("{}计划创建不足,剩余需要创建个数{},使用历史遗漏素材创建", strategy.getAccountId(), remindCnt);
                 //优先创建历史遗漏素材
-                remindCnt = this.createCreative(strategy, 3, remindCnt,openUrl);
+                remindCnt = this.createCreative(token, strategy, 3, remindCnt,openUrl);
             }
             if (remindCnt >= 1) {
                 log.info("{}计划创建不足,剩余需要创建个数{},使用高质量素材创建", strategy.getAccountId(), remindCnt);
                 //高质量素材
-                remindCnt = this.createCreative(strategy, 2, remindCnt,openUrl);
+                remindCnt = this.createCreative(token, strategy, 2, remindCnt,openUrl);
             }
             if (remindCnt >= 1) {
                 //历史打捞素材
                 log.info("{}计划创建不足,剩余需要创建个数{},使用历史打捞素材创建", strategy.getAccountId(), remindCnt);
-                this.createCreative(strategy, 4, remindCnt,openUrl);
+                this.createCreative(token, strategy, 4, remindCnt,openUrl);
             }
+            //获取最新的plan计划更新到表格
+            String nowDate = DateUtils.formatDate();
+            advertiserDataService.getAdvertiserPlan(token, "", nowDate, nowDate);
+
+            int newUnitCreateCnt = planService.queryToDayBuiltCount(strategy.getAccountId());
+            AiBytedanceAutocreateLog iBytedanceAutocreateLog = new AiBytedanceAutocreateLog(
+                    strategy.getAccountId(),
+                    "创建广告计划",
+                    200,
+                    "当前账户需要创建计划总数为"+unitNum+"个,截止目前有"+unitCreateCnt+"个,此次创建成功"+(newUnitCreateCnt - unitCreateCnt)+"个。",
+                    "aiBytedanceAdvertiserStrategyService.customCreativeSupplement => strategy:"+ strategy.toString()+",hour:"+hour);
+            iBytedanceAutocreateLogService.save(iBytedanceAutocreateLog);
         }catch (Exception e){
             log.info(e.getMessage());
         }
@@ -1597,5 +1789,50 @@ public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiByte
         return Result.successMsg("获取橙子建站站点列表成功。",dataList);
     }
 
+    /**
+     *查询 组名称 计划名称
+     */
+    @Override
+    public Result getStrategyInfoByName(AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy) {
+        //查询 组名称
+        QueryWrapper<AiBytedanceAdvertiserStrategy> queryWrapperCampaign = new QueryWrapper<>();
+        //查询计划名称
+        QueryWrapper<AiBytedanceAdvertiserStrategy> queryWrapperAdName = new QueryWrapper<>();
+        List<AiBytedanceAdvertiserStrategy> strategyInfoCampain = new ArrayList<>();
+        List<AiBytedanceAdvertiserStrategy> strategyInfoAdName = new ArrayList<>();
+        //新增
+        if (Check.isNull(aiBytedanceAdvertiserStrategy.getId())){
+            queryWrapperCampaign.eq("campaign_name",aiBytedanceAdvertiserStrategy.getCampaignName());
+            strategyInfoCampain = aiBytedanceAdvertiserStrategyMapper.selectList(queryWrapperCampaign);
+            if (!Check.isNull(strategyInfoCampain)){
+                return Result.error("新创建的账户配置已存在相同的组名称【"+aiBytedanceAdvertiserStrategy.getCampaignName()+"】请修改后重新保存。");
+            }
+            queryWrapperAdName.eq("ad_name",aiBytedanceAdvertiserStrategy.getAdName());
+            strategyInfoAdName = aiBytedanceAdvertiserStrategyMapper.selectList(queryWrapperAdName);
+            if (!Check.isNull(strategyInfoAdName)){
+                return Result.error("新创建的账户配置已存在相同的计划名称【"+aiBytedanceAdvertiserStrategy.getAdName()+"】请修改后重新保存。");
+            }
+        // 编辑
+        }else {
+            queryWrapperCampaign.eq("campaign_name",aiBytedanceAdvertiserStrategy.getCampaignName());
+            strategyInfoCampain = aiBytedanceAdvertiserStrategyMapper.selectList(queryWrapperCampaign);
+            strategyInfoCampain.stream().map(AiBytedanceAdvertiserStrategy::getId).collect(Collectors.toList());
+            if (!Check.isNull(strategyInfoCampain) &&
+                    !strategyInfoCampain.stream().map(AiBytedanceAdvertiserStrategy::getId).collect(Collectors.toList()).contains(aiBytedanceAdvertiserStrategy.getId())){
+                return Result.error("新创建的账户配置已存在相同的组名称【"+aiBytedanceAdvertiserStrategy.getCampaignName()+"】请修改后重新保存。");
+            }
+            queryWrapperAdName.eq("ad_name",aiBytedanceAdvertiserStrategy.getAdName());
+            strategyInfoAdName = aiBytedanceAdvertiserStrategyMapper.selectList(queryWrapperAdName);
+            if (!Check.isNull(strategyInfoAdName) &&
+                    !strategyInfoAdName.stream().map(AiBytedanceAdvertiserStrategy::getId).collect(Collectors.toList()).contains(aiBytedanceAdvertiserStrategy.getId())){
+                return Result.error("新创建的账户配置已存在相同的计划名称【"+aiBytedanceAdvertiserStrategy.getAdName()+"】请修改后重新保存。");
+            }
+        }
+
+
+
+        return Result.successMsg("成功。",null);
+    }
+
 
 }

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

@@ -0,0 +1,19 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAutocreateLog;
+import org.jeecg.modules.bytedance.advertise.service.IAiBytedanceAutocreateLogService;
+import org.jeecg.modules.bytedance.advertise.mapper.AiBytedanceAutocreateLogMapper;
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+/**
+ * 自动创建计划日志
+ * @author jeecg-boot
+ * 2021-07-05
+ * @version V1.0
+ */
+@Service
+public class AiBytedanceAutocreateLogServiceImpl extends ServiceImpl<AiBytedanceAutocreateLogMapper, AiBytedanceAutocreateLog> implements IAiBytedanceAutocreateLogService {
+
+}

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

@@ -210,6 +210,20 @@ public class ByteDanceAdvertisePlanServiceImpl extends ServiceImpl<ByteDanceAdve
     }
 
     @Override
+    public List<ByteDanceAdvertisePlan> getAllPlansByAccountId(Long accountId,String adModifyTime) {
+        QueryWrapper<ByteDanceAdvertisePlan>queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id",accountId+"");
+        if(null!=adModifyTime&&!"".equals(adModifyTime.trim())){
+            queryWrapper.ge("ad_modify_time",adModifyTime);
+            queryWrapper.le("ad_modify_time",new Date());
+        }
+        queryWrapper.ne("toutiao_status","AD_STATUS_DELETE");
+//        queryWrapper.eq("toutiao_status","AD_STATUS_AUDIT_DENY");   //获取通过审核建议
+        queryWrapper.orderByDesc("ad_modify_time");
+        return this.list(queryWrapper);
+    }
+
+    @Override
     public int queryToDayBuiltCount(Long accountId) {
         String date = DateUtil.formatDate(new Date());
         return byteDanceAdvertisePlanMapper.queryTodayBuiltCount(accountId, date);

+ 7 - 2
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/ByteDanceGeneralCopywriterServiceImpl.java

@@ -39,7 +39,7 @@ public class ByteDanceGeneralCopywriterServiceImpl extends ServiceImpl<ByteDance
     IUserAllocationService IUserAllocationService;
 
     @Override
-    public Result getGeneralCopywriterReport(String userId, String accountId, String keyWord, String startTime, String endTime, Integer pageNum, Integer pageSize){
+    public Result getGeneralCopywriterReport(String userId, String accountId, String keyWord, Integer status, String startTime, String endTime, Integer pageNum, Integer pageSize){
 
 
         List<String> accountIds = new ArrayList<>();
@@ -62,7 +62,7 @@ public class ByteDanceGeneralCopywriterServiceImpl extends ServiceImpl<ByteDance
 
 
         PageHelper.startPage(pageNum,pageSize);
-        List<Map<String, Object>> generalCopywriteReportList = byteDanceGeneralCopywriterMapper.selectGeneralCopywriterReport(accountIds,keyWord, startTime, endTime);
+        List<Map<String, Object>> generalCopywriteReportList = byteDanceGeneralCopywriterMapper.selectGeneralCopywriterReport(accountIds, keyWord, status, startTime, endTime);
         if(Check.isNull(generalCopywriteReportList)){
             return Result.successMsg("还没有此文案报表数据,请将此文案投放跑量!",generalCopywriteReportList);
         }
@@ -119,4 +119,9 @@ public class ByteDanceGeneralCopywriterServiceImpl extends ServiceImpl<ByteDance
         return byteDanceGeneralCopywriterMapper.selectCreativeWordPackageByName(name);
     }
 
+    @Override
+    public List<ByteDanceGeneralCopywriter> selectAllDataByTextCopywriter(String textCopywriter){
+        return byteDanceGeneralCopywriterMapper.selectAllDataByTextCopywriter(textCopywriter);
+    }
+
 }

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

@@ -44,20 +44,49 @@ public class ByteDanceVideoInfoServiceImpl extends ServiceImpl<ByteDanceVideoInf
     }
 
     @Override
-    public List<ByteDanceVideoInfo> listByParams(Long projectId,Long accountId, String startTime, String endTime, Long videoCnt,long creativeCnt) {
+    public List<ByteDanceVideoInfo> listByParams(Long projectId,Long accountId, String imageMode,String startTime, String endTime, Long videoCnt,long creativeCnt) {
         String now = DateUtils.formatDate();
-        return videoInfoMapper.getNewVideoByParams(projectId,accountId,startTime,endTime,videoCnt,creativeCnt,now);
+        return videoInfoMapper.getNewVideoByParams(projectId,accountId,imageMode,startTime,endTime,videoCnt,creativeCnt,now);
     }
 
     @Override
-    public List<ByteDanceVideoInfo> topMatByParams(Long projectId, Long accountId, String startTime, String endTime, Long videoCnt) {
+    public List<ByteDanceVideoInfo> topMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt) {
         String now = DateUtils.formatDate();
-        return videoInfoMapper.topMatByParams(projectId,accountId,startTime,endTime,videoCnt,now);
+        return videoInfoMapper.topMatByParams(projectId,accountId,imageMode,startTime,endTime,videoCnt,now);
     }
 
     @Override
-    public List<ByteDanceVideoInfo> historyMatByParams(Long projectId, Long accountId, String startTime, String endTime, Long videoCnt) {
+    public List<ByteDanceVideoInfo> historyMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt) {
         String now = DateUtils.formatDate();
-        return videoInfoMapper.historyMatByParams(projectId,accountId,startTime,endTime,videoCnt,now);
+        return videoInfoMapper.historyMatByParams(projectId,accountId,imageMode,startTime,endTime,videoCnt,now);
+    }
+
+
+    /**
+     * 图片 上新 遗漏
+     */
+    @Override
+    public List<ByteDanceVideoInfo> imageListByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt, long creativeCnt) {
+        String now = DateUtils.formatDate();
+        return videoInfoMapper.imageListByParams(projectId,accountId,imageMode,startTime,endTime,videoCnt,creativeCnt,now);
+
+    }
+
+    /**
+     * 图片 跑量
+     */
+    @Override
+    public List<ByteDanceVideoInfo> imageTopMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt) {
+        String now = DateUtils.formatDate();
+        return videoInfoMapper.imageTopMatByParams(projectId,accountId,imageMode,startTime,endTime,videoCnt,now);
+    }
+
+    /**
+     * 图片 打捞
+     */
+    @Override
+    public List<ByteDanceVideoInfo> imageHistoryMatByParams(Long projectId, Long accountId, String imageMode,String startTime, String endTime, Long videoCnt) {
+        String now = DateUtils.formatDate();
+        return videoInfoMapper.imageHistoryMatByParams(projectId,accountId,imageMode,startTime,endTime,videoCnt,now);
     }
 }

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

@@ -0,0 +1,131 @@
+package org.jeecg.modules.bytedance.advertise.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.bytedance.advertise.entity.*;
+import org.jeecg.modules.bytedance.advertise.mapper.BytedanceMaterialRejectReasonMapper;
+import org.jeecg.modules.bytedance.advertise.mapper.BytedancePlanRejectReasonMapper;
+import org.jeecg.modules.bytedance.advertise.mapper.LowQualityRejectReasonMapper;
+import org.jeecg.modules.bytedance.advertise.mapper.RuleDataAccountMapper;
+import org.jeecg.modules.bytedance.advertise.service.BytedanceRejectReasonService;
+import org.jeecg.modules.bytedance.advertise.service.IRuleDataAccountService;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.utils.Check;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.CancellationException;
+
+/**
+ * 规则账户清洗数据
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2020-11-16
+ */
+@Service
+public class BytedanceRejectReasonServiceImpl implements BytedanceRejectReasonService {
+
+    @Resource
+    private BytedancePlanRejectReasonMapper bytedancePlanRejectReasonMapper;
+
+    @Resource
+    private BytedanceMaterialRejectReasonMapper BytedanceMaterialRejectReasonMapper;
+
+    @Resource
+    LowQualityRejectReasonMapper lowQualityRejectReasonMapper;
+    public void saveRejectReasonToDb(JSONArray jsonArray,Long accountId){
+        for(int i=0; i<jsonArray.size(); i++){
+            JSONObject jsonObject = jsonArray.getJSONObject(i);
+            JSONObject ad_reject = jsonObject.getJSONObject("ad_reject");
+            JSONArray reject_data = ad_reject.getJSONArray("reject_data");
+            if(!Check.isNull(reject_data)){
+                for(int j=0; j<reject_data.size();j++){
+                    JSONObject object = reject_data.getJSONObject(j);
+                    BytedancePlanRejectReason bytedancePlanRejectReason = new BytedancePlanRejectReason();
+                    bytedancePlanRejectReason.setAdId(ad_reject.getLong("ad_id"));
+                    bytedancePlanRejectReason.setRejectItem(object.getString("reject_item"));
+                    bytedancePlanRejectReason.setRejectReason(object.getString("reject_reason"));
+                    bytedancePlanRejectReason.setIsLowQuality(0);
+                    bytedancePlanRejectReason.setAccountId(accountId);
+                    String[] rejectReasons = bytedancePlanRejectReason.getRejectReason().split("广告体验优化建议:");
+                    if(rejectReasons.length == 0){
+                        LowQualityRejectReason lowQualityRejectReason = lowQualityRejectReasonMapper.getByRejectReason(bytedancePlanRejectReason.getRejectReason().trim());
+                        if(!Check.isNull(lowQualityRejectReason)){
+                            bytedancePlanRejectReason.setIsLowQuality(1);
+                        }
+                    }else {
+                        for(int k=1;k<rejectReasons.length;k++){
+                            LowQualityRejectReason lowQualityRejectReason = lowQualityRejectReasonMapper.getByRejectReason("广告体验优化建议:"+rejectReasons[k].trim());
+                            if(!Check.isNull(lowQualityRejectReason)){
+                                bytedancePlanRejectReason.setIsLowQuality(1);
+                            }
+                        }
+                    }
+
+                    int res = bytedancePlanRejectReasonMapper.replaceIntoDb(bytedancePlanRejectReason);
+                    if(res == 0){
+                        System.out.println(bytedancePlanRejectReason.toString());
+                    }
+                }
+            }
+
+            JSONArray material_reject = jsonObject.getJSONArray("material_reject");
+            if(!Check.isNull(material_reject)){
+                for(int j=0; j<material_reject.size();j++){
+                    JSONObject object = material_reject.getJSONObject(j);
+                    BytedanceMaterialRejectReason bytedanceMaterialRejectReason = new BytedanceMaterialRejectReason();
+                    bytedanceMaterialRejectReason.setRejectReason(object.getString("reject_reason"));
+                    bytedanceMaterialRejectReason.setIsLowQuality(0);
+                    bytedanceMaterialRejectReason.setAccountId(accountId);
+                    String[] rejectReasons = bytedanceMaterialRejectReason.getRejectReason().split("广告体验优化建议:");
+                    for(int k=1;k<rejectReasons.length;k++){
+                        LowQualityRejectReason lowQualityRejectReason = lowQualityRejectReasonMapper.getByRejectReason("广告体验优化建议:"+rejectReasons[k].trim());
+                        if(!Check.isNull(lowQualityRejectReason)){
+                            bytedanceMaterialRejectReason.setIsLowQuality(1);
+                        }
+                    }
+                    if(rejectReasons.length == 0){
+                        LowQualityRejectReason lowQualityRejectReason = lowQualityRejectReasonMapper.getByRejectReason(bytedanceMaterialRejectReason.getRejectReason().trim());
+                        if(!Check.isNull(lowQualityRejectReason)){
+                            bytedanceMaterialRejectReason.setIsLowQuality(1);
+                        }
+                    }else {
+                        for(int k=1;k<rejectReasons.length;k++){
+                            LowQualityRejectReason lowQualityRejectReason = lowQualityRejectReasonMapper.getByRejectReason("广告体验优化建议:"+rejectReasons[k].trim());
+                            if(!Check.isNull(lowQualityRejectReason)){
+                                bytedanceMaterialRejectReason.setIsLowQuality(1);
+                            }
+                        }
+                    }
+                    if(!Check.isNull(object.getString("title"))){
+                        bytedanceMaterialRejectReason.setTitle(object.getString("title"));
+                    }
+                    if(!Check.isNull(object.getJSONArray("image_id"))){
+                        bytedanceMaterialRejectReason.setImageId(object.getJSONArray("image_id").toJSONString());
+                    }
+                    if(!Check.isNull(object.getString("video_id"))){
+                        bytedanceMaterialRejectReason.setVideoId(object.getString("video_id"));
+                    }
+                    if(!Check.isNull(ad_reject.getLong("ad_id"))){
+                        bytedanceMaterialRejectReason.setAdId(ad_reject.getLong("ad_id"));
+                    }
+                    int res =  BytedanceMaterialRejectReasonMapper.replaceIntoDb(bytedanceMaterialRejectReason);
+                    if(res == 0){
+                        System.out.println(bytedanceMaterialRejectReason.toString());
+                    }
+//                    BytedanceMaterialRejectReasonMapper.insert(bytedanceMaterialRejectReason);
+                }
+            }
+        }
+    }
+
+
+}

+ 6 - 2
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/advertise/service/impl/BytedanceVideoSlogenInfoServiceImpl.java

@@ -62,7 +62,7 @@ public class BytedanceVideoSlogenInfoServiceImpl extends ServiceImpl<BytedanceVi
         return this.list(queryWrapper);
     }
     @Override
-    public Result getVideoSlogenReport(String userId, String projectId,String keyWord, String startTime, String endTime, Integer pageNum, Integer pageSize){
+    public Result getVideoSlogenReport(String userId, String projectId,String keyWord,Integer status, String startTime, String endTime, Integer pageNum, Integer pageSize){
 
         List<String> projectIdList = new ArrayList<>();
         //查询普通用户的全量查询,当前用户所有项目
@@ -75,7 +75,7 @@ public class BytedanceVideoSlogenInfoServiceImpl extends ServiceImpl<BytedanceVi
         }
 
         PageHelper.startPage(pageNum,pageSize);
-        List<Map<String, Object>> videoSlogenReportList = bytedanceVideoSlogenInfoMapper.selectVideoSlogenReportByAccountIdAndTitle(projectIdList, keyWord, startTime, endTime);
+        List<Map<String, Object>> videoSlogenReportList = bytedanceVideoSlogenInfoMapper.selectVideoSlogenReportByAccountIdAndTitle(projectIdList, keyWord, status, startTime, endTime);
 
         if(Check.isNull(videoSlogenReportList)){
             return Result.successMsg("还没有此文案报表数据,请将此文案投放跑量!",videoSlogenReportList);
@@ -127,4 +127,8 @@ public class BytedanceVideoSlogenInfoServiceImpl extends ServiceImpl<BytedanceVi
         PageInfo<Map<String, Object>> pageInfo = new PageInfo<Map<String, Object>>(videoSlogenReportList);
         return Result.successMsg("数据加载成功。",pageInfo);
     }
+    @Override
+    public List<BytedanceVideoSlogenInfo> getVideoSlogenBySlogenAndProjectId(String slogen, Long projectId){
+        return bytedanceVideoSlogenInfoMapper.getDataBySlogenAndProjectId(slogen, projectId);
+    }
 }

+ 1 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/IMaterialInfoService.java

@@ -14,7 +14,7 @@ import java.util.List;
  * @date 2019-10-11
  */
 public interface IMaterialInfoService extends IService<MaterialInfo> {
-    MaterialInfo getParams(String signature, Integer status);
+    MaterialInfo getParams(String signature, Integer status,Long projectId);
 
 
     Result updMaterialOfflineById(List<String> ids, Integer offlineFlag);

+ 4 - 1
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/service/impl/MaterialInfoServiceImpl.java

@@ -31,7 +31,7 @@ public class MaterialInfoServiceImpl extends ServiceImpl<MaterialInfoMapper, Mat
 
 
     @Override
-    public MaterialInfo getParams(String signature, Integer status) {
+    public MaterialInfo getParams(String signature, Integer status,Long projectId) {
         QueryWrapper<MaterialInfo>queryWrapper = new QueryWrapper<>();
         if(null!=signature&&!"".equals(signature.trim())){
             queryWrapper.eq("code",signature);
@@ -39,6 +39,9 @@ public class MaterialInfoServiceImpl extends ServiceImpl<MaterialInfoMapper, Mat
         if(null!=status){
             queryWrapper.eq("status",status);
         }
+        if(null!=projectId){
+            queryWrapper.eq("project_id",projectId);
+        }
         queryWrapper.orderByDesc("create_time").last("limit 1");
         return this.getOne(queryWrapper);
     }

+ 3 - 3
jeecg-boot-bytedance/src/main/java/org/jeecg/modules/bytedance/common/utils/GetCampaignNum.java

@@ -22,15 +22,15 @@ public class GetCampaignNum {
 
         Long zu = countNum / campaignAdCnt;
         Long yu = countNum % campaignAdCnt;
-        System.out.println("余---"+yu);
+        //System.out.println("余---"+yu);
         // 不能整除 有余数 则 组 = 商 + 1
         // 整除 组 = 商
         Long count = yu != 0 ? zu.intValue()+1 : zu;
        // 账户配置中的组数量 < 当前 组序号
         if (count.intValue() <= campaignCnt){
-            System.out.println("序号----------"+count);
+            System.out.println("序号----------"+count);
         }else {
-            System.out.println("序号-超过了最大值-----"+count);
+            System.out.println("序号-超过了规定的最大值-----"+count);
         }
         return count;
     }

+ 31 - 11
jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/AiBytedanceAdvertiserStrategyController.java

@@ -1,5 +1,6 @@
 package org.jeecg.modules.bytedance.advertise.controller;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -11,9 +12,11 @@ import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.system.query.QueryGenerator;
 import org.jeecg.modules.bytedance.advertise.dockapi.MarketingService;
 import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAdvertiserStrategy;
+import org.jeecg.modules.bytedance.advertise.entity.AiBytedanceAutocreateLog;
 import org.jeecg.modules.bytedance.advertise.entity.RuleDataAccount;
 import org.jeecg.modules.bytedance.advertise.entity.UpdAdStaOrCpaOrBudget;
 import org.jeecg.modules.bytedance.advertise.service.IAiBytedanceAdvertiserStrategyService;
+import org.jeecg.modules.bytedance.advertise.service.IAiBytedanceAutocreateLogService;
 import org.jeecg.modules.bytedance.advertise.service.IRuleDataAccountService;
 import org.jeecg.modules.bytedance.advertise.vo.AdConvertQueryVo;
 import org.jeecg.modules.bytedance.advertise.vo.AdGroupSearchVo;
@@ -30,10 +33,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -125,6 +125,14 @@ public class AiBytedanceAdvertiserStrategyController {
 	@PostMapping(value = "/addBytedanceStrategy")
 	public Result addBytedanceStrategy(@RequestBody AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy) {
 		try {
+			//复制功能 防止前端传id到后台
+			aiBytedanceAdvertiserStrategy.setId(null);
+			// 组名称 计划名称 是否重复
+			/*Result<AiBytedanceAdvertiserStrategy> resultName = aiBytedanceAdvertiserStrategyService.getStrategyInfoByName(aiBytedanceAdvertiserStrategy);
+			if (!resultName.isSuccess()) {
+				return Result.error(resultName.getMessage());
+			}*/
+
 			return aiBytedanceAdvertiserStrategyService.addBytedanceStrategy(aiBytedanceAdvertiserStrategy);
 		} catch (Exception e) {
 			log.error(e.getMessage(),e);
@@ -140,6 +148,13 @@ public class AiBytedanceAdvertiserStrategyController {
 	@ApiOperation(value="头条智能投放账户配置信息表-编辑", notes="头条智能投放账户配置信息表-编辑")
 	@PutMapping(value = "/edit")
 	public Result<AiBytedanceAdvertiserStrategy> edit(@RequestBody AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy) {
+		// 组名称 计划名称 是否重复
+		/*
+		Result<AiBytedanceAdvertiserStrategy> resultName = aiBytedanceAdvertiserStrategyService.getStrategyInfoByName(aiBytedanceAdvertiserStrategy);
+		if (!resultName.isSuccess()) {
+			return Result.errorMsg(resultName.getMessage());
+		}
+		*/
 		CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(aiBytedanceAdvertiserStrategy.getAccountId()));
 		//修改后预算金额不能低于当前已消费金额的105%
 		QueryWrapper<RuleDataAccount> ruleDataAccountQueryWrapper = new QueryWrapper<>();
@@ -266,9 +281,10 @@ public class AiBytedanceAdvertiserStrategyController {
 	@PutMapping(value = "/updStaById")
 	public Result updStaById(@RequestParam("id")String id,
 							 @ApiParam("状态(0开-1关)") @RequestParam("state") String state,
-							 @ApiParam("账户id") @RequestParam("accountId") String accountId) {
+							 @ApiParam("账户id") @RequestParam("accountId") String accountId,
+							 @ApiParam("素材类型") @RequestParam("creativeImageMode") String creativeImageMode) {
 		try {
-			return aiBytedanceAdvertiserStrategyService.updStaById(id,state,accountId);
+			return aiBytedanceAdvertiserStrategyService.updStaById(id,state,accountId,creativeImageMode);
 		}catch (Exception e){
 			log.error("修改状态(0开-1关)失败",e);
 			return Result.error("请求失败,请联系开发人员!");
@@ -434,15 +450,19 @@ public class AiBytedanceAdvertiserStrategyController {
 	@GetMapping(value = "/getAdAudiencePackage")
 	public Result getAdAudiencePackage(@RequestParam(value = "accountId",required = false) String accountId,
 									   @RequestParam(value = "landingType",required = false) String landingType,
-									   @RequestParam(value = "deliveryRange",required = false,defaultValue = "DEFAULT") String deliveryRange) {
+									   @RequestParam(value = "deliveryRange",required = false) String deliveryRange) {
 		try {
 			if (Check.isNull(accountId)){
 				return Result.errorMsg("请选择账户。");
 			}
-			/*if (Check.isNull(landingType)){
-				return Result.errorMsg("投放内容不能为空");
-			}*/
-			return aiBytedanceAdvertiserStrategyService.getAdAudiencePackage(accountId,landingType,deliveryRange);
+			// 默认 定向包
+			Result resultDefault = aiBytedanceAdvertiserStrategyService.getAdAudiencePackage(accountId,landingType,"DEFAULT");
+			//穿山甲定向包
+			Result resultUnion = aiBytedanceAdvertiserStrategyService.getAdAudiencePackage(accountId,landingType,"UNION");
+			List listDefault = (List) resultDefault.getResult();
+			List listUnion = (List) resultUnion.getResult();
+			listDefault.addAll(listUnion);
+			return Result.successMsg("获取定向包成功。",listDefault);
 		}catch (Exception e){
 			log.error("获取定向包异常",e);
 			return Result.error("请求失败,请联系开发人员!");

+ 95 - 14
jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/BytedanceGeneralCopywriterController.java

@@ -1,19 +1,21 @@
 package org.jeecg.modules.bytedance.advertise.controller;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.common.util.oConvertUtils;
 import org.jeecg.modules.bytedance.advertise.entity.ByteDanceCreativeWordPackage;
 import org.jeecg.modules.bytedance.advertise.entity.ByteDanceGeneralCopywriter;
 import org.jeecg.modules.bytedance.advertise.service.IByteDanceGeneralCopywriterService;
-import org.jeecg.modules.bytedance.advertise.service.impl.ByteDanceGeneralCopywriterServiceImpl;
 import org.jeecg.modules.bytedance.common.utils.Check;
 import org.jeecg.modules.bytedance.common.utils.ExcelUtil;
 import org.jeecg.modules.bytedance.common.utils.StringUtils;
@@ -145,7 +147,9 @@ public class BytedanceGeneralCopywriterController {
                                       @RequestParam(value = "startTime",defaultValue = "") String startTime,
                                       @RequestParam(value = "endTime",defaultValue = "") String endTime,
                                       @RequestParam(value = "pageNo", defaultValue="1") Integer pageNo,
-                                      @RequestParam(value = "pageSize", defaultValue="10") Integer pageSize
+                                      @RequestParam(value = "pageSize", defaultValue="10") Integer pageSize,
+                                      @RequestParam(value = "status",required = false)  Integer status
+
     ) {
         try {
 
@@ -158,7 +162,7 @@ public class BytedanceGeneralCopywriterController {
                 accountId = "admin";	//传递projectId为admin
             }
 
-            return byteDanceGeneralCopywriterService.getGeneralCopywriterReport(userId,accountId,keyWord, startTime,endTime,pageNo,pageSize);
+            return byteDanceGeneralCopywriterService.getGeneralCopywriterReport(userId, accountId, keyWord, status, startTime, endTime, pageNo, pageSize);
         }catch (Exception e){
             log.error("通用文案数据-获取文案维度创意报表数据异常",e);
             return Result.error("请求失败,请联系开发人员!");
@@ -210,20 +214,69 @@ public class BytedanceGeneralCopywriterController {
      * @return
      */
     @ApiOperation(value="通用文案库-编辑", notes="通用文案库-编辑")
-    @PutMapping(value = "/edit")
+    @PostMapping(value = "/edit")
     public Result<ByteDanceGeneralCopywriter> edit(@RequestBody ByteDanceGeneralCopywriter byteDanceGeneralCopywriter) {
-        Result<ByteDanceGeneralCopywriter> result = new Result<ByteDanceGeneralCopywriter>();
-        ByteDanceGeneralCopywriter byteDanceGeneralCopywriterEntity = byteDanceGeneralCopywriterService.getById(byteDanceGeneralCopywriter.getId());
-        if(byteDanceGeneralCopywriterEntity==null) {
-            result.error500("未找到对应实体");
-        }else {
+
+        Result<ByteDanceGeneralCopywriter> result = new Result<>();
+        try{
+            ByteDanceGeneralCopywriter byteDanceGeneralCopywriterEntity = byteDanceGeneralCopywriterService.getById(byteDanceGeneralCopywriter.getId());
+            if(byteDanceGeneralCopywriterEntity==null) {
+                return result.error500("未找到对应实体");
+            }
+//            LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+            byteDanceGeneralCopywriter.setUpdateTime(new Date());
+
+            String title = byteDanceGeneralCopywriter.getTextCopywriter();
+            title = title.trim().replaceAll("[\\{]{2,}", "{");
+            title = title.trim().replaceAll("[\\}]{2,}", "}");
+
+            String reg = "\\{[\\u4e00-\\u9fa5\\-]{2,6}\\}";
+            Pattern pattern = Pattern.compile(reg);
+            Matcher matcher = pattern.matcher(title);
+            JSONArray creativeWordIdsArray = new JSONArray();
+
+            int len = StringUtils.lengthAsSlogan(title);
+            int left = title.indexOf("{");
+            int right = title.indexOf("}");
+            if (left >= 0 || right >= 0) {
+                int times = 0;
+                while (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
+                    times++;
+                    if (times >= 3) {
+                        return result.error500("动态词包不合法,词包数量超过2个");
+                    }
+                    String matchStr = matcher.group();//获取当前匹配的值
+                    title = title.replace(matchStr,"");
+
+                    ByteDanceCreativeWordPackage creativeWordPackage = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(matchStr.substring(1, matchStr.length() - 1));
+                    if (Check.isNull(creativeWordPackage)) {
+                        return result.error500("动态词包不合法,词包不存在或者含有单独的非词包大括号");
+                    }
+                    creativeWordIdsArray.add(creativeWordPackage.getCreativeWordId());
+                    len = len - (right - left) + creativeWordPackage.getMaxWordLen();
+                    left = title.indexOf("{");
+                    right = title.indexOf("}");
+                }
+                if(title.contains("{") || title.contains("}")){
+                    return result.error500("文案含有词包特殊字符,请检查");
+                }
+                byteDanceGeneralCopywriter.setCreativeWordIds(creativeWordIdsArray.toJSONString());
+            }
+            //校验标题长度,长度小于5和大于30的全部过滤
+            if (len < 5 || len > 30) {
+                return result.error500("文案长度不合法,小于5或大于30");
+            }
+
             boolean ok = byteDanceGeneralCopywriterService.updateById(byteDanceGeneralCopywriter);
             if(ok) {
                 result.success("修改成功!");
+                result.setCode(0);
             }
+            return result;
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            return result.error500("操作失败");
         }
-
-        return result;
     }
 
     /**
@@ -234,15 +287,28 @@ public class BytedanceGeneralCopywriterController {
     @ApiOperation(value="通用文案库-通过id删除", notes="通用文案库-通过id删除")
     @DeleteMapping(value = "/delete")
     public Result<?> delete(@RequestParam(name="id") String id) {
+        Result result = new Result();
         try {
-            byteDanceGeneralCopywriterService.removeById(id);
+            ByteDanceGeneralCopywriter generalCopywriter = byteDanceGeneralCopywriterService.getById(id);
+            if(null == generalCopywriter||generalCopywriter.getStatus() == 0){
+                return result.ok("此文案不存在或者已经被删除");
+            }
+            generalCopywriter.setStatus(0);
+            generalCopywriter.setUpdateTime(new Date());
+            boolean ok = byteDanceGeneralCopywriterService.updateById(generalCopywriter);
+            if(ok){
+                result.setMessage("删除成功!");
+                result.setCode(0);
+            }
+            return result;
         } catch (Exception e) {
             log.error("删除失败",e.getMessage());
-            return Result.error("删除失败!");
+            return result.error500("删除失败!");
         }
-        return Result.ok("删除成功!");
+
     }
 
+
     /**
      *  批量删除
      * @param ids
@@ -280,6 +346,21 @@ public class BytedanceGeneralCopywriterController {
         return result;
     }
 
+    @ApiOperation(value="通用文案库-通过id查询", notes="通用文案库-通过id查询")
+    @GetMapping(value = "/queryByTextCopywriter")
+    public Result<List<ByteDanceGeneralCopywriter>> queryByCopywriter(@RequestParam(name="textCopywriter",required=true) String textCopywriter) {
+        Result<List<ByteDanceGeneralCopywriter>> result = new Result<>();
+        List<ByteDanceGeneralCopywriter> byteDanceGeneralCopywriter = byteDanceGeneralCopywriterService.selectAllDataByTextCopywriter(textCopywriter);
+        if(byteDanceGeneralCopywriter==null) {
+            result.error500("未找到对应实体");
+        }else {
+            result.setResult(byteDanceGeneralCopywriter);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+
     /**
      * 导出excel
      *

+ 111 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/BytedanceRejectReasonController.java

@@ -0,0 +1,111 @@
+package org.jeecg.modules.bytedance.advertise.controller;
+
+import com.alibaba.fastjson.JSONArray;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.bytedance.advertise.dockapi.MarketingService;
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
+import org.jeecg.modules.bytedance.advertise.service.BytedanceRejectReasonService;
+import org.jeecg.modules.bytedance.advertise.service.IByteDanceAdvertisePlanService;
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
+import org.jeecg.modules.bytedance.common.service.ICtopOauthTokenService;
+import org.jeecg.modules.bytedance.common.utils.Check;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 广告计划审核建议
+ * @author hxc
+ * 2021-06-28
+ * @version V1.0
+ */
+@Slf4j
+@Api(tags="广告计划审核建议")
+@RestController
+@RequestMapping("/ctop/bytedanceRejectReason")
+public class BytedanceRejectReasonController {
+
+
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(5);
+    @Autowired
+    MarketingService marketingService;
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    IByteDanceAdvertisePlanService byteDanceAdvertisePlanService;
+    @Autowired
+    BytedanceRejectReasonService bytedanceRejectReasonService;
+
+    /**
+     *  编辑
+     * @param hour : 获取当前时间近几个小时的数据。根据广告计划表,近hour个小时新增进来的计划信息,更新他们的审核建议
+     * @return
+     */
+    @ApiOperation(value="广告计划审核建议-从接口获取数据落库", notes="广告计划审核建议-从接口获取数据落库")
+    @GetMapping(value = "/getReasonInRecentHours")
+    public Result getReasonInRecentHours(@RequestParam(value = "hour",required = false) Integer hour) {
+        Result result = new Result();
+        List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+        if (null == tokens || tokens.isEmpty()) {
+            System.out.println("未获取到token");
+            result.setCode(500);
+            result.setMessage("未获取到token");
+            return result;
+        }
+
+        System.out.println("---------------------------------->>"+tokens.size()+"个token<<----------------------------------");
+
+        tokens.forEach(token -> executorService.submit(()->getRejectReasonByToken(token, hour)));
+
+
+        return result.success("调用任务已开启");
+    }
+
+
+    public void getRejectReasonByToken(CtopOauthToken token, Integer hour){
+
+            if(token.getAccessTokenExpiresIn().before(new Date())){
+                log.info("token已过期,accountId ==> {}",token.getAccountId());
+                return;
+            }
+
+            List<ByteDanceAdvertisePlan> allPlansByAccountId = byteDanceAdvertisePlanService.getAllPlansByAccountId(token.getAccountId(), Check.isNull(hour)?null:DateUtils.formatDate(DateUtils.addHour(new Date(),-hour),"yyyy-MM-dd HH:mm:ss"));
+
+            if(Check.isNull(allPlansByAccountId) || allPlansByAccountId.size() < 1){
+                return;
+            }
+            List<String> adids = new ArrayList<>();
+            allPlansByAccountId.forEach(plan -> adids.add(plan.getId().toString()));
+
+
+            while(adids.size() > 10){
+                List<String> mulAdids = adids.subList(0,10);
+//                System.out.println("查询的计划是"+Arrays.toString(mulAdids.toArray()));
+                Result dataListResult = marketingService.getRejectReason(token, token.getAccountId().toString(), mulAdids);
+                if(dataListResult.getMessage().toString().contains("No permission to operate account")){
+                    return;
+                }
+                if(Check.isNull(dataListResult.getResult()) || dataListResult.getCode().equals(500)){
+                    continue;
+                }
+                JSONArray jsonArray = JSONArray.parseArray(dataListResult.getResult().toString());
+                bytedanceRejectReasonService.saveRejectReasonToDb(jsonArray,token.getAccountId());
+                adids.removeAll(mulAdids);
+            }
+            Result dataListResult = marketingService.getRejectReason(token, token.getAccountId().toString(), adids);
+            if(Check.isNull(dataListResult.getResult())|| dataListResult.getCode().equals(500)){
+                return;
+            }
+            JSONArray jsonArray = JSONArray.parseArray(dataListResult.getResult().toString());
+            bytedanceRejectReasonService.saveRejectReasonToDb(jsonArray,token.getAccountId());
+        }
+
+}

+ 83 - 22
jeecg-boot-module-system/src/main/java/org/jeecg/modules/bytedance/advertise/controller/BytedanceVideoSlogenInfoController.java

@@ -26,10 +26,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -67,7 +64,7 @@ public class BytedanceVideoSlogenInfoController {
 																 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
 																 HttpServletRequest req) {
 		Result<IPage<BytedanceVideoSlogenInfo>> result = new Result<>();
-		slogenInfo.setStatus(1);
+//		slogenInfo.setStatus(1);		//默认不传为所有,传了1是正常,传0是已删除
 		QueryWrapper<BytedanceVideoSlogenInfo> queryWrapper = QueryGenerator.initQueryWrapper(slogenInfo, req.getParameterMap());
 		Page<BytedanceVideoSlogenInfo> page = new Page<>(pageNo, pageSize);
 		IPage<BytedanceVideoSlogenInfo> pageList = bytedanceVideoSlogenInfoService.page(page, queryWrapper);
@@ -84,7 +81,8 @@ public class BytedanceVideoSlogenInfoController {
 									  @RequestParam(value = "startTime",defaultValue = "") String startTime,
 									  @RequestParam(value = "endTime",defaultValue = "") String endTime,
 									  @RequestParam(value = "pageNo", defaultValue="1") Integer pageNo,
-									  @RequestParam(value = "pageSize", defaultValue="10") Integer pageSize
+									  @RequestParam(value = "pageSize", defaultValue="10") Integer pageSize,
+									  @RequestParam(value = "status",required = false) Integer status
 									) {
 		try {
 			//查询用户角色
@@ -96,7 +94,7 @@ public class BytedanceVideoSlogenInfoController {
 			if ("admin".equals(roleCode) && Check.isNull(projectId)) {
 				projectId = "admin";	//传递projectId为admin
 			}
-			return bytedanceVideoSlogenInfoService.getVideoSlogenReport(userId, projectId,keyWord, startTime,endTime,pageNo,pageSize);
+			return bytedanceVideoSlogenInfoService.getVideoSlogenReport(userId, projectId,keyWord,status, startTime,endTime,pageNo,pageSize);
 		}catch (Exception e){
 			log.error("指定文案-获取指定文案维度创意报表数据异常",e);
 			return Result.error("请求失败,请联系开发人员!");
@@ -208,18 +206,16 @@ public class BytedanceVideoSlogenInfoController {
 	public Result<BytedanceVideoSlogenInfo> edit(@RequestBody BytedanceVideoSlogenInfo slogenInfo) {
 		Result<BytedanceVideoSlogenInfo> result = new Result<>();
 		try{
-		BytedanceVideoSlogenInfo bytedanceVideoSlogenInfoEntity = bytedanceVideoSlogenInfoService.getById(slogenInfo.getId());
-		if(bytedanceVideoSlogenInfoEntity==null) {
-			result.error500("未找到对应实体");
-			return result;
+			List<BytedanceVideoSlogenInfo> videoSlogenInfoList = bytedanceVideoSlogenInfoService.getVideoSlogenBySlogenAndProjectId(slogenInfo.getSlogan(),slogenInfo.getProjectId());
+		if(videoSlogenInfoList==null) {
+			return result.error500("未找到对应实体");
 		}
-		LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
-		slogenInfo.setUpdateBy(user.getId());
-		slogenInfo.setUpdateTime(new Date());
 
-		String title = slogenInfo.getSlogan();
+
+		String title = slogenInfo.getNewSlogan();
 		title = title.trim().replaceAll("[\\{]{2,}", "{");
 		title = title.trim().replaceAll("[\\}]{2,}", "}");
+		slogenInfo.setNewSlogan(title);
 
 		String reg = "\\{[\\u4e00-\\u9fa5\\-]{2,6}\\}";
 		Pattern pattern = Pattern.compile(reg);
@@ -234,14 +230,14 @@ public class BytedanceVideoSlogenInfoController {
 			while (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
 				times++;
 				if (times >= 3) {
-					return Result.errorMsg("动态词包不合法,词包数量超过2个");
+					return result.error500("动态词包不合法,词包数量超过2个");
 				}
 				String matchStr = matcher.group();//获取当前匹配的值
 				title = title.replace(matchStr,"");
 
 				ByteDanceCreativeWordPackage creativeWordPackage = byteDanceGeneralCopywriterService.selectCreativeWordPackageByName(matchStr.substring(1, matchStr.length() - 1));
 				if (Check.isNull(creativeWordPackage)) {
-					return Result.errorMsg("动态词包不合法,词包不存在或者含有单独的非词包大括号");
+					return result.error500("动态词包不合法,词包不存在或者含有单独的非词包大括号");
 				}
 				creativeWordIdsArray.add(creativeWordPackage.getCreativeWordId());
 				len = len - (right - left) + creativeWordPackage.getMaxWordLen();
@@ -251,16 +247,26 @@ public class BytedanceVideoSlogenInfoController {
 			if(title.contains("{") || title.contains("}")){
 				return result.error500("文案含有词包特殊字符,请检查");
 			}
-			slogenInfo.setCreativeWordIds(creativeWordIdsArray.toJSONString());
 		}
 		//校验标题长度,长度小于5和大于30的全部过滤
 		if (len < 5 || len > 30) {
 			return result.error500("文案长度不合法,小于5或大于30");
 		}
 
-		bytedanceVideoSlogenInfoService.updateById(slogenInfo);
-		result.success("修改成功!");
-		result.setCode(0);
+			LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+			for (BytedanceVideoSlogenInfo videoSlogenInfo:videoSlogenInfoList
+				 ) {
+				videoSlogenInfo.setSlogan(slogenInfo.getNewSlogan());
+				videoSlogenInfo.setUpdateBy(user.getId());
+				videoSlogenInfo.setUpdateTime(new Date());
+				videoSlogenInfo.setCreativeWordIds(creativeWordIdsArray.toJSONString());
+			}
+
+		boolean ok = bytedanceVideoSlogenInfoService.updateBatchById(videoSlogenInfoList);
+			if(ok) {
+				result.success("修改成功!");
+				result.setCode(0);
+			}
 		return result;
 		} catch (Exception e) {
 			log.error(e.getMessage(),e);
@@ -275,7 +281,7 @@ public class BytedanceVideoSlogenInfoController {
 	 * @return
 	 */
 	@ApiOperation(value="头条视频文案信息-通过id删除", notes="头条视频文案信息-通过id删除")
-	@PostMapping(value = "/delete")
+	@DeleteMapping(value = "/delete")
 	public Result<?> delete(@RequestParam(name="id") String id) {
 		try {
 			BytedanceVideoSlogenInfo slogenInfo = bytedanceVideoSlogenInfoService.getById(id);
@@ -293,6 +299,37 @@ public class BytedanceVideoSlogenInfoController {
 			return Result.error("删除失败!");
 		}
 	}
+	/**
+	 *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-通过id删除", notes="头条视频文案信息-通过id删除")
+	@DeleteMapping(value = "/deleteBySlogenAndProjectId")
+	public Result<?> deleteBySlogenAndProjectId(@RequestParam(name="slogan") String slogan, @RequestParam(name="projectId") Long projectId) {
+		try {
+			Result result = new Result();
+			List<BytedanceVideoSlogenInfo> videoSlogenInfoList = bytedanceVideoSlogenInfoService.getVideoSlogenBySlogenAndProjectId(slogan,projectId);
+			if(Check.isNull(videoSlogenInfoList)) {
+				return result.ok("此文案不存在或者已经被删除");
+			}
+			LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+			videoSlogenInfoList.forEach(videoSlogenInfo->{
+				videoSlogenInfo.setStatus(0);
+				videoSlogenInfo.setUpdateTime(new Date());
+				videoSlogenInfo.setCreateBy(user.getId());});
+
+			boolean ok = bytedanceVideoSlogenInfoService.updateBatchById(videoSlogenInfoList);
+			if(ok) {
+				result.success("删除成功!");
+				result.setCode(0);
+			}
+			return result;
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+	}
 
 	/**
 	 * 通过id查询
@@ -312,4 +349,28 @@ public class BytedanceVideoSlogenInfoController {
 		result.setSuccess(true);
 		return result;
 	}
+
+	/**
+	 * 通过slogen和projectId查询
+	 * @param id
+	 * @return
+	 */
+	@ApiOperation(value="头条视频文案信息-通过文案内容和项目id查询", notes="头条视频文案信息-通过文案内容和项目id查询")
+	@GetMapping(value = "/queryBySlogenAndProjectId")
+	public Result<BytedanceVideoSlogenInfo> queryBySlogenAndProjectId(@RequestParam(name="slogan") String slogan, @RequestParam(name="projectId") Long projectId) {
+
+		Result<BytedanceVideoSlogenInfo> result = new Result<>();
+		List<BytedanceVideoSlogenInfo> videoSlogenInfoList = bytedanceVideoSlogenInfoService.getVideoSlogenBySlogenAndProjectId(slogan,projectId);
+		if(Check.isNull(videoSlogenInfoList)) {
+			result.error500("未找到对应实体");
+			return result;
+		}
+        List<String> materialNameArray = new ArrayList<>();
+        videoSlogenInfoList.forEach(videoSlogenInfo->materialNameArray.add(videoSlogenInfo.getMaterialName()));
+        BytedanceVideoSlogenInfo bytedanceVideoSlogenInfo = videoSlogenInfoList.get(0);
+        bytedanceVideoSlogenInfo.setMaterialNameArray(materialNameArray);
+		result.setResult(bytedanceVideoSlogenInfo);
+		result.setSuccess(true);
+		return result;
+	}
 }

+ 37 - 1
jeecg-boot-module-system/src/main/resources/application-dev.yml

@@ -1,5 +1,5 @@
 server:
-  port: 8080
+  port: 8808
   tomcat:
     max-swallow-size: -1
   error:
@@ -287,3 +287,39 @@ justauth:
     type: default
     prefix: 'demo::'
     timeout: 1h
+
+bytedance:
+  appId: 1635316529903624
+  secret: 0c51523e90d6166418fc8421a4896808e90e26f4
+  url:
+    auth-prefix: https://ad.oceanengine.com/openapi
+    api-prefix: https://ad.oceanengine.com/open_api
+    callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+    refresh-token: /oauth2/refresh_token
+    advertiser-info: /2/advertiser/public_info/
+    ad-get: /2/ad/get/
+    ad-create: /2/ad/create/
+    ad-update: /2/ad/update/
+    ad-update-status: /2/ad/update/status/
+    ad-update-bid: /2/ad/update/bid/
+    ad-update-budget: /2/ad/update/budget/
+    ad-update-reject-reason: 2/ad/reject_reason/
+    campaign-get: /2/campaign/get/
+    campaign-create: /2/campaign/create/
+    campaign-update-status: /2/campaign/update/status/
+    campaign-update: /2/campaign/update/
+    dmp-custom-audience-select: /2/dmp/custom_audience/select/
+    file-video-ad: /2/file/video/ad/
+    file-image-ad: /2/file/image/ad/
+    creative-update-status: /2/creative/update/status/
+    creative-material-get: /2/creative/material/read/
+    creative-create-v2: /2/creative/create_v2/
+    creative-get: /2/creative/get/
+    creative-read: /2/creative/read_v2/
+    creative-update: /2/creative/update_v2/
+    creative-reject-reason: /2/creative/reject_reason/
+    advertiser-report-get: /2/report/advertiser/get/
+    campaign-report-get: /2/report/campaign/get/
+    ad-report-get: /2/report/ad/get/
+    ad-creative-get: /2/report/creative/get/
+    advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/

+ 329 - 0
jeecg-boot-module-system/src/main/resources/application-pre.yml

@@ -0,0 +1,329 @@
+server:
+  port: 8808
+  tomcat:
+    max-swallow-size: -1
+  error:
+    include-exception: true
+    include-stacktrace: ALWAYS
+    include-message: ALWAYS
+  servlet:
+    context-path: /bytedance-api
+  compression:
+    enabled: true
+    min-response-size: 1024
+    mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
+
+management:
+ endpoints:
+  web:
+   exposure:
+    include: metrics,httptrace
+
+spring:
+  servlet:
+     multipart:
+        max-file-size: 10MB
+        max-request-size: 10MB
+  mail:
+    host: smtp.163.com
+    username: jeecgos@163.com
+    password: ??
+    properties:
+      mail:
+        smtp:
+          auth: true
+          starttls:
+            enable: true
+            required: true
+  ## quartz定时任务,采用数据库方式
+  quartz:
+    job-store-type: jdbc
+    initialize-schema: embedded
+    #设置自动启动,默认为 true
+    auto-startup: true
+    #启动时更新己存在的Job
+    overwrite-existing-jobs: true
+    properties:
+      org:
+        quartz:
+          scheduler:
+            instanceName: MyScheduler
+            instanceId: AUTO
+          jobStore:
+            class: org.quartz.impl.jdbcjobstore.JobStoreTX
+            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
+            tablePrefix: QRTZ_
+            isClustered: true
+            misfireThreshold: 60000
+            clusterCheckinInterval: 10000
+          threadPool:
+            class: org.quartz.simpl.SimpleThreadPool
+            threadCount: 10
+            threadPriority: 5
+            threadsInheritContextClassLoaderOfInitializingThread: true
+  #json 时间戳统一转换
+  jackson:
+    date-format:   yyyy-MM-dd HH:mm:ss
+    time-zone:   GMT+8
+  jpa:
+    open-in-view: false
+  activiti:
+    check-process-definitions: false
+    #启用作业执行器
+    async-executor-activate: false
+    #启用异步执行器
+    job-executor-activate: false
+  aop:
+    proxy-target-class: true
+  #配置freemarker
+  freemarker:
+    # 设置模板后缀名
+    suffix: .ftl
+    # 设置文档类型
+    content-type: text/html
+    # 设置页面编码格式
+    charset: UTF-8
+    # 设置页面缓存
+    cache: false
+    prefer-file-system-access: false
+    # 设置ftl文件路径
+    template-loader-path:
+      - classpath:/templates
+  # 设置静态文件路径,js,css等
+  mvc:
+    static-path-pattern: /**
+  resource:
+    static-locations: classpath:/static/,classpath:/public/
+  autoconfigure:
+    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
+  datasource:
+    druid:
+      stat-view-servlet:
+        enabled: true
+        loginUsername: admin
+        loginPassword: 123456
+        allow:
+      web-stat-filter:
+        enabled: true
+    dynamic:
+      druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
+        # 连接池的配置信息
+        # 初始化大小,最小,最大
+        initial-size: 5
+        min-idle: 5
+        maxActive: 1000
+        # 配置获取连接等待超时的时间
+        maxWait: 60000
+        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+        timeBetweenEvictionRunsMillis: 60000
+        # 配置一个连接在池中最小生存的时间,单位是毫秒
+        minEvictableIdleTimeMillis: 300000
+        validationQuery: SELECT 1 FROM DUAL
+        testWhileIdle: true
+        testOnBorrow: false
+        testOnReturn: false
+        # 打开PSCache,并且指定每个连接上PSCache的大小
+        poolPreparedStatements: true
+        maxPoolPreparedStatementPerConnectionSize: 20
+        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
+        filters: stat,wall,slf4j
+        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
+        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
+      datasource:
+        master:
+          url: jdbc:mysql://139.186.27.96:4000/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          username: data
+          password: hcst@2021
+          driver-class-name: com.mysql.cj.jdbc.Driver
+          # 多数据源配置
+          #multi-datasource1:
+          #url: jdbc:mysql://localhost:3306/jeecg-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          #username: root
+          #password: root
+          #driver-class-name: com.mysql.cj.jdbc.Driver
+  #redis 配置
+  redis:
+    database: 0
+    host: 172.30.0.17
+    lettuce:
+      pool:
+        max-active: 8   #最大连接数据库连接数,设 0 为没有限制
+        max-idle: 8     #最大等待连接中的数量,设 0 为没有限制
+        max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
+        min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
+      shutdown-timeout: 100ms
+    password: hcst@2021..
+    port: 6379
+#mybatis plus 设置
+mybatis-plus:
+  mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml
+  global-config:
+    # 关闭MP3.0自带的banner
+    banner: false
+    db-config:
+      #主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
+      id-type: ASSIGN_ID
+      # 默认数据库表下划线命名
+      table-underline: true
+  configuration:
+    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
+    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    # 返回类型为Map,显示null对应的字段
+    call-setters-on-nulls: true
+#minidao 设置
+minidao :
+  base-package: org.jeecg.modules.jmreport.*
+  db-type: mysql
+#jeecg专用配置
+jeecg :
+  # 本地:local\Minio:minio\阿里云:alioss
+  uploadType: alioss
+  path :
+    #文件上传根目录 设置
+    upload: /opt/jeecg-boot/upload
+    #webapp文件路径
+    webapp: /opt/jeecg-boot/webapp
+  shiro:
+     excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
+  #阿里云oss存储配置
+  oss:
+    endpoint: oss-cn-beijing.aliyuncs.com
+    accessKey: ??
+    secretKey: ??
+    bucketName: jeecgos
+    staticDomain: https://static.jeecg.com
+  # ElasticSearch 设置
+  elasticsearch:
+    cluster-name: jeecg-ES
+    cluster-nodes: 111.225.222.176:9200
+    check-enabled: true
+  # 表单设计器配置
+  desform:
+    # 主题颜色(仅支持 16进制颜色代码)
+    theme-color: "#1890ff"
+    # 文件、图片上传方式,可选项:qiniu(七牛云)、system(跟随系统配置)
+    upload-type: system
+  # 在线预览文件服务器地址配置
+  file-view-domain: http://fileview.jeecg.com
+  # minio文件上传
+  minio:
+    minio_url: http://minio.jeecg.com
+    minio_name: ??
+    minio_pass: ??
+    bucketName: otatest
+  #大屏报表参数设置
+  jmreport:
+    mode: prod
+    #数据字典是否进行saas数据隔离,自己看自己的字典
+    saas: false
+    #是否需要校验token
+    is_verify_token: true
+    #必须校验方法
+    verify_methods: remove,delete,save,add,update
+  #Wps在线文档
+  wps:
+    domain: https://wwo.wps.cn/office/
+    appid: ??
+    appsecret: ??
+  #xxl-job配置
+  xxljob:
+    enabled: false
+    adminAddresses: http://127.0.0.1:9080/xxl-job-admin
+    appname: ${spring.application.name}
+    accessToken: ''
+    address: 127.0.0.1:30007
+    ip: 127.0.0.1
+    port: 30007
+    logPath: logs/jeecg/job/jobhandler/
+    logRetentionDays: 30
+   #自定义路由配置 yml nacos database
+  route:
+    config:
+      data-id: jeecg-gateway-router
+      group: DEFAULT_GROUP
+      data-type: yml
+  #分布式锁配置
+  redisson:
+    address: 127.0.0.1:6379
+    password:
+    type: STANDALONE
+    enabled: true
+#cas单点登录
+cas:
+  prefixUrl: http://cas.example.org:8443/cas
+#Mybatis输出sql日志
+logging:
+  level:
+    org.jeecg.modules.system.mapper : info
+#swagger
+knife4j:
+  production: false
+  basic:
+    enable: false
+    username: jeecg
+    password: jeecg1314
+#第三方登录
+justauth:
+  enabled: true
+  type:
+    GITHUB:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/github/callback
+    WECHAT_ENTERPRISE:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_enterprise/callback
+      agent-id: 1000002
+    DINGTALK:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/dingtalk/callback
+    WECHAT_OPEN:
+      client-id: ??
+      client-secret: ??
+      redirect-uri: http://sso.test.com:8080/jeecg-boot/sys/thirdLogin/wechat_open/callback
+  cache:
+    type: default
+    prefix: 'demo::'
+    timeout: 1h
+
+
+
+
+
+bytedance:
+  appId: 1635316529903624
+  secret: 0c51523e90d6166418fc8421a4896808e90e26f4
+  url:
+    auth-prefix: https://ad.oceanengine.com/openapi
+    api-prefix: https://ad.oceanengine.com/open_api
+    callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+    refresh-token: /oauth2/refresh_token
+    advertiser-info: /2/advertiser/public_info/
+    ad-get: /2/ad/get/
+    ad-create: /2/ad/create/
+    ad-update: /2/ad/update/
+    ad-update-status: /2/ad/update/status/
+    ad-update-bid: /2/ad/update/bid/
+    ad-update-budget: /2/ad/update/budget/
+    ad-update-reject-reason: 2/ad/reject_reason/
+    campaign-get: /2/campaign/get/
+    campaign-create: /2/campaign/create/
+    campaign-update-status: /2/campaign/update/status/
+    campaign-update: /2/campaign/update/
+    dmp-custom-audience-select: /2/dmp/custom_audience/select/
+    file-video-ad: /2/file/video/ad/
+    file-image-ad: /2/file/image/ad/
+    creative-update-status: /2/creative/update/status/
+    creative-material-get: /2/creative/material/read/
+    creative-create-v2: /2/creative/create_v2/
+    creative-get: /2/creative/get/
+    creative-read: /2/creative/read_v2/
+    creative-update: /2/creative/update_v2/
+    creative-reject-reason: /2/creative/reject_reason/
+    advertiser-report-get: /2/report/advertiser/get/
+    campaign-report-get: /2/report/campaign/get/
+    ad-report-get: /2/report/ad/get/
+    ad-creative-get: /2/report/creative/get/
+    advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/

+ 41 - 2
jeecg-boot-module-system/src/main/resources/application-prod.yml

@@ -1,5 +1,5 @@
 server:
-  port: 8080
+  port: 8808
   tomcat:
     max-swallow-size: -1
   error:
@@ -286,4 +286,43 @@ justauth:
   cache:
     type: default
     prefix: 'demo::'
-    timeout: 1h
+    timeout: 1h
+
+
+
+
+bytedance:
+  appId: 1635316529903624
+  secret: 0c51523e90d6166418fc8421a4896808e90e26f4
+  url:
+    auth-prefix: https://ad.oceanengine.com/openapi
+    api-prefix: https://ad.oceanengine.com/open_api
+    callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+    refresh-token: /oauth2/refresh_token
+    advertiser-info: /2/advertiser/public_info/
+    ad-get: /2/ad/get/
+    ad-create: /2/ad/create/
+    ad-update: /2/ad/update/
+    ad-update-status: /2/ad/update/status/
+    ad-update-bid: /2/ad/update/bid/
+    ad-update-budget: /2/ad/update/budget/
+    ad-update-reject-reason: 2/ad/reject_reason/
+    campaign-get: /2/campaign/get/
+    campaign-create: /2/campaign/create/
+    campaign-update-status: /2/campaign/update/status/
+    campaign-update: /2/campaign/update/
+    dmp-custom-audience-select: /2/dmp/custom_audience/select/
+    file-video-ad: /2/file/video/ad/
+    file-image-ad: /2/file/image/ad/
+    creative-update-status: /2/creative/update/status/
+    creative-material-get: /2/creative/material/read/
+    creative-create-v2: /2/creative/create_v2/
+    creative-get: /2/creative/get/
+    creative-read: /2/creative/read_v2/
+    creative-update: /2/creative/update_v2/
+    creative-reject-reason: /2/creative/reject_reason/
+    advertiser-report-get: /2/report/advertiser/get/
+    campaign-report-get: /2/report/campaign/get/
+    ad-report-get: /2/report/ad/get/
+    ad-creative-get: /2/report/creative/get/
+    advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/

+ 38 - 2
jeecg-boot-module-system/src/main/resources/application-test.yml

@@ -1,5 +1,5 @@
 server:
-  port: 8080
+  port: 8808
   tomcat:
     max-swallow-size: -1
   error:
@@ -152,7 +152,7 @@ spring:
          max-wait: -1ms  #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
          min-idle: 0     #最小等待连接中的数量,设 0 为没有限制
        shutdown-timeout: 100ms
-     password: ''
+     password: hcst@2020
      port: 6379
 #mybatis plus 设置
 mybatis-plus:
@@ -287,3 +287,39 @@ justauth:
     type: default
     prefix: 'demo::'
     timeout: 1h
+
+bytedance:
+  appId: 1635316529903624
+  secret: 0c51523e90d6166418fc8421a4896808e90e26f4
+  url:
+    auth-prefix: https://ad.oceanengine.com/openapi
+    api-prefix: https://ad.oceanengine.com/open_api
+    callback-url: http://adsp.c-top.com.cn:8080/jeecg-boot/bytedance
+    refresh-token: /oauth2/refresh_token
+    advertiser-info: /2/advertiser/public_info/
+    ad-get: /2/ad/get/
+    ad-create: /2/ad/create/
+    ad-update: /2/ad/update/
+    ad-update-status: /2/ad/update/status/
+    ad-update-bid: /2/ad/update/bid/
+    ad-update-budget: /2/ad/update/budget/
+    ad-update-reject-reason: 2/ad/reject_reason/
+    campaign-get: /2/campaign/get/
+    campaign-create: /2/campaign/create/
+    campaign-update-status: /2/campaign/update/status/
+    campaign-update: /2/campaign/update/
+    dmp-custom-audience-select: /2/dmp/custom_audience/select/
+    file-video-ad: /2/file/video/ad/
+    file-image-ad: /2/file/image/ad/
+    creative-update-status: /2/creative/update/status/
+    creative-material-get: /2/creative/material/read/
+    creative-create-v2: /2/creative/create_v2/
+    creative-get: /2/creative/get/
+    creative-read: /2/creative/read_v2/
+    creative-update: /2/creative/update_v2/
+    creative-reject-reason: /2/creative/reject_reason/
+    advertiser-report-get: /2/report/advertiser/get/
+    campaign-report-get: /2/report/campaign/get/
+    ad-report-get: /2/report/ad/get/
+    ad-creative-get: /2/report/creative/get/
+    advertiser-fund-daily-stat: /2/advertiser/fund/daily_stat/