Prechádzať zdrojové kódy

Merge branch 'V1.1.8'

# Conflicts:
#	jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TestController.java
zhaoxian 3 rokov pred
rodič
commit
4e3248aea3
31 zmenil súbory, kde vykonal 2071 pridanie a 246 odobranie
  1. 123 85
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TestController.java
  2. 12 1
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/constant/MatchLogic.java
  3. 142 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/AlarmRuleOperationRecord.java
  4. 12 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleAccountThreshold.java
  5. 4 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleBase.java
  6. 15 1
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleGroup.java
  7. 6 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleIndicator.java
  8. 20 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/AlarmRuleOperationRecordMapper.java
  9. 14 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/xml/AlarmRuleOperationRecordMapper.xml
  10. 17 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/ExternalLinkService.java
  11. 15 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/IAlarmRuleOperationRecordService.java
  12. 19 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/AlarmRuleOperationRecordServiceImpl.java
  13. 1 1
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/xml/AlarmRuleRecordServiceImpl.java
  14. 42 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/ExternalLinkServiceImpl.java
  15. 618 80
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleGroupServiceImpl.java
  16. 13 4
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/RuleDataAccountKuaishouServiceImpl.java
  17. 13 4
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/RuleDataAccountServiceImpl.java
  18. 94 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AlarmRuleRebackJob.java
  19. 39 0
      module-job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/ExploreReportJob.java
  20. 3 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/app/mapper/KuaishouAccountBalanceBudgetMapper.java
  21. 6 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/app/mapper/xml/KuaishouAccountBalanceBudgetMapper.xml
  22. 0 2
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/batch/service/impl/KuaiShouUpdateServiceImpl.java
  23. 36 23
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/controller/KuaishouGroupExploreController.java
  24. 275 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/controller/KuaishouReportDailyExploreController.java
  25. 141 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouReportDailyExplore.java
  26. 30 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/KuaishouReportDailyExploreMapper.java
  27. 103 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaishouReportDailyExploreMapper.xml
  28. 5 5
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/IKuaishouGroupExploreService.java
  29. 28 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/IKuaishouReportDailyExploreService.java
  30. 54 40
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouGroupExploreServiceImpl.java
  31. 171 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouReportDailyExploreServiceImpl.java

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 123 - 85
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TestController.java


+ 12 - 1
module-alarm/src/main/java/cn/com/ctop/alarm/modules/constant/MatchLogic.java

@@ -42,8 +42,19 @@ public class MatchLogic {
             }
             obj.put("isNull", false);
             if ("number".equals(type)) {
-                BigDecimal bigThr = new BigDecimal(threshold);
                 BigDecimal bigVal = new BigDecimal(value);
+                if (threshold.contains("~")) {
+                    String[] split = threshold.split("~");
+                    BigDecimal min = new BigDecimal(split[0]);
+                    BigDecimal max = new BigDecimal(split[1]);
+                    //bigVal介于min与max之间,即:min<=bigVal<=max
+                    if (max.compareTo(bigVal) > -1 && bigVal.compareTo(min) > -1) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+                BigDecimal bigThr = new BigDecimal(threshold);
                 switch (condition) {
                     case "equal":
                         return bigVal.compareTo(bigThr) == 0;

+ 142 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/AlarmRuleOperationRecord.java

@@ -0,0 +1,142 @@
+package cn.com.ctop.alarm.modules.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 预警操作记录表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-08-10
+ */
+@Data
+@TableName("ctop_alarm_rule_operation_record")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_alarm_rule_operation_record对象", description = "预警操作记录表")
+public class AlarmRuleOperationRecord {
+
+    /**
+     * 主键id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /**
+     * 账户ID
+     */
+    @Excel(name = "账户ID", width = 15)
+    @ApiModelProperty(value = "账户ID")
+    private Long accountId;
+    /**
+     * 计划ID
+     */
+    @Excel(name = "计划ID", width = 15)
+    @ApiModelProperty(value = "计划ID")
+    private Long planId;
+    /**
+     * 组ID
+     */
+    @Excel(name = "组ID", width = 15)
+    @ApiModelProperty(value = "组ID")
+    private Long unitId;
+    /**
+     * 规则组id
+     */
+    @Excel(name = "规则组id", width = 15)
+    @ApiModelProperty(value = "规则组id")
+    private Long groupId;
+    /**
+     * 指标code
+     */
+    @Excel(name = "指标code", width = 15)
+    @ApiModelProperty(value = "指标code")
+    private String indicatorCode;
+    /**
+     * 操作记录
+     */
+    private String message;
+    /**
+     * 修改前的值
+     */
+    @Excel(name = "修改前的值", width = 15)
+    @ApiModelProperty(value = "修改前的值")
+    private String beforeValue;
+    /**
+     * 操作类型:up-提高,down-降低,to-调整至
+     */
+    @Excel(name = "操作类型:up-提高,down-降低,to-调整至", width = 15)
+    @ApiModelProperty(value = "操作类型:up-提高,down-降低,to-调整至")
+    private String operationType;
+    /**
+     * 操作内容:price-金额,percent-百分数
+     */
+    @Excel(name = "操作内容:price-金额,percent-百分数", width = 15)
+    @ApiModelProperty(value = "操作内容:price-金额,percent-百分数")
+    private String operationValue;
+    /**
+     * 修改后的值
+     */
+    @Excel(name = "修改后的值", width = 15)
+    @ApiModelProperty(value = "修改后的值")
+    private String afterValue;
+    /**
+     * 操作阈值
+     */
+    @Excel(name = "操作阈值", width = 15)
+    @ApiModelProperty(value = "操作阈值")
+    private String operationThreshold;
+    /**
+     * 峰值
+     */
+    @Excel(name = "峰值", width = 15)
+    @ApiModelProperty(value = "峰值")
+    private String MaxValue;
+    /**
+     * 峰值
+     */
+    @Excel(name = "最小值", width = 15)
+    @ApiModelProperty(value = "最小值")
+    private String minValue;
+    /**
+     * 操作时间
+     */
+    @Excel(name = "操作时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "操作时间")
+    private String valueTime;
+    /**
+     * 媒体类型
+     */
+    @Excel(name = "媒体类型", width = 15)
+    @ApiModelProperty(value = "媒体类型")
+    private String mediaType;
+    /**
+     * createTime
+     */
+    @Excel(name = "createTime", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "createTime")
+    private Date createTime;
+    /**
+     * updateTime
+     */
+    @Excel(name = "updateTime", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "updateTime")
+    private Date updateTime;
+}

+ 12 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleAccountThreshold.java

@@ -55,6 +55,18 @@ public class RuleAccountThreshold {
     @ApiModelProperty(value = "阈值")
     private String threshold;
     /**
+     * 操作阈值
+     */
+    private String operationThreshold;
+    /**
+     * 峰值
+     */
+    private String maxValue;
+    /**
+     * 低值
+     */
+    private String minValue;
+    /**
      * createTime
      */
     @ApiModelProperty(value = "createTime")

+ 4 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleBase.java

@@ -48,6 +48,10 @@ public class RuleBase {
     @ApiModelProperty(value = "指标code")
     private String indicatorCode;
     /**
+     * 比较指标code
+     */
+    private String cindicatorCode;
+    /**
      * 判断条件 大于 等于 小于等
      */
     @Excel(name = "判断条件 大于 等于 小于等", width = 15)

+ 15 - 1
module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleGroup.java

@@ -55,9 +55,23 @@ public class RuleGroup {
     @ApiModelProperty(value = "规则关系 当rule_type 为group时必填 and同时命中  or 命中一条")
     private String ruleRelationship;
     /**
-     * 操作内容:SEND发送,PAUSE关停并发送
+     * 操作内容:SEND-发送,PAUSE-关停并发送,BUDGET-修改预算,BID-出价,TIME-投放时间
      */
     private String operate;
+
+    /**
+     * 是否有后续操作,0无,1有
+     */
+    private Integer operation;
+
+    /**
+     * 操作类型:up-提高,down-降低,to-调整至
+     */
+    private String operationType;
+    /**
+     * 操作内容:price-金额,percent-百分数
+     */
+    private String operationValue;
     /**
      * 预警发送方式: SMS:短信,WeChat:企业微信,EMAIL:电子邮件,TEL:电话
      */

+ 6 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/entity/RuleIndicator.java

@@ -38,6 +38,11 @@ public class RuleIndicator {
     @Excel(name = "1:头条2:快手", width = 15)
     @ApiModelProperty(value = "1:头条2:快手")
     private Integer mediaType;
+
+    /**
+     * 是否可操作指标,0否,1是
+     */
+    private Integer operation;
     /**
      * 指标名称
      */
@@ -57,6 +62,7 @@ public class RuleIndicator {
     @ApiModelProperty(value = "数据类型")
     private String dataType;
     private String modelType;
+    private String conditionType;
     /**
      * 数据单位
      */

+ 20 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/AlarmRuleOperationRecordMapper.java

@@ -0,0 +1,20 @@
+package cn.com.ctop.alarm.modules.mapper;
+
+import cn.com.ctop.alarm.modules.entity.AlarmRuleOperationRecord;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 预警操作记录表
+ *
+ * @author jeecg-boot
+ * 2021-08-10
+ * @version V1.0
+ */
+public interface AlarmRuleOperationRecordMapper extends BaseMapper<AlarmRuleOperationRecord> {
+
+    List<AlarmRuleOperationRecord> queryToBeRestoredInfo(@Param("type") String type,@Param("time") String time);
+}

+ 14 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/xml/AlarmRuleOperationRecordMapper.xml

@@ -0,0 +1,14 @@
+<?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="cn.com.ctop.alarm.modules.mapper.AlarmRuleOperationRecordMapper">
+
+    <select id="queryToBeRestoredInfo" resultType="cn.com.ctop.alarm.modules.entity.RuleAccountThreshold">
+        SELECT id, account_id,unit_id,before_value,after_value,create_time from
+            ctop_alarm_rule_operation_record
+        where message ='success'
+          AND value_time = #{time}
+          AND indicator_code = 'TIME'
+          AND media_type = #{type}
+        GROUP BY unit_id
+    </select>
+</mapper>

+ 17 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/ExternalLinkService.java

@@ -0,0 +1,17 @@
+package cn.com.ctop.alarm.modules.service;
+
+import cn.com.ctop.alarm.modules.entity.RuleCondition;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.math.BigDecimal;
+
+/**
+ * @Description: 调用外部接口
+ * @Author: jeecg-boot
+ * @Date: 2020-11-16
+ * @Version: V1.0
+ */
+public interface ExternalLinkService {
+
+    String editBytedancePlanCpaBidOrBudget(Long accountId, String adId, BigDecimal cpaBid, String adScheduleTime,Long budget);
+}

+ 15 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/IAlarmRuleOperationRecordService.java

@@ -0,0 +1,15 @@
+package cn.com.ctop.alarm.modules.service;
+
+import cn.com.ctop.alarm.modules.entity.AlarmRuleOperationRecord;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 预警操作记录表
+ *
+ * @author jeecg-boot
+ * 2021-08-10
+ * @version V1.0
+ */
+public interface IAlarmRuleOperationRecordService extends IService<AlarmRuleOperationRecord> {
+
+}

+ 19 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/AlarmRuleOperationRecordServiceImpl.java

@@ -0,0 +1,19 @@
+package cn.com.ctop.alarm.modules.service.impl;
+
+import cn.com.ctop.alarm.modules.entity.AlarmRuleOperationRecord;
+import cn.com.ctop.alarm.modules.mapper.AlarmRuleOperationRecordMapper;
+import cn.com.ctop.alarm.modules.service.IAlarmRuleOperationRecordService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * 预警操作记录表
+ *
+ * @author jeecg-boot
+ * 2021-08-10
+ * @version V1.0
+ */
+@Service
+public class AlarmRuleOperationRecordServiceImpl extends ServiceImpl<AlarmRuleOperationRecordMapper, AlarmRuleOperationRecord> implements IAlarmRuleOperationRecordService {
+
+}

+ 1 - 1
module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/xml/AlarmRuleRecordServiceImpl.java

@@ -1,4 +1,4 @@
-package cn.com.ctop.alarm.modules.mapper.xml;
+package cn.com.ctop.alarm.modules.service.impl;
 
 import cn.com.ctop.alarm.modules.entity.AlarmRuleRecord;
 import cn.com.ctop.alarm.modules.mapper.AlarmRuleRecordMapper;

+ 42 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/ExternalLinkServiceImpl.java

@@ -0,0 +1,42 @@
+package cn.com.ctop.alarm.modules.service.impl;
+
+import cn.com.ctop.alarm.modules.service.ExternalLinkService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+
+/**
+ * 调取外部接口
+ */
+@Slf4j
+@Service
+public class ExternalLinkServiceImpl implements ExternalLinkService {
+    //修改头条CPABID出价,投放时间
+    private static final String URL_UPDATE_CPABID = "http://139.186.165.84:8808/bytedance-api/advertiser/bytedanceReportController/updateADCpaBid";
+    //线上IP  http://118.24.244.213:8808/bytedance-api/advertiser/bytedanceReportController/updateADCpaBid
+    //测试IP  http://139.186.165.84:8808/bytedance-api/advertiser/bytedanceReportController/updateADCpaBid
+
+    @Override
+    public String editBytedancePlanCpaBidOrBudget(Long accountId, String adId, BigDecimal cpaBid, String adScheduleTime, Long budget) {
+        StringBuffer buf = new StringBuffer();
+        buf.append("?accountId=").append(accountId).append("&adId=").append(adId);
+        if (!Check.isNull(cpaBid)) {
+            buf.append("&cpaBid=").append(cpaBid);
+        }
+        if (!Check.isNull(adScheduleTime)) {
+            buf.append("&adScheduleTime=").append(adScheduleTime);
+        }
+        if (!Check.isNull(budget)) {
+            buf.append("&budget=").append(budget);
+        }
+        log.info("调用微服务接口,修改头条计划出价、预算、投放时间段。。。。。。start");
+        HttpUtils.httpGet(URL_UPDATE_CPABID + buf.toString(), null, null);
+        log.info("调用微服务接口,修改头条计划出价、预算、投放时间段。。。。。。end");
+        return null;
+    }
+
+
+}

+ 618 - 80
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleGroupServiceImpl.java

@@ -2,6 +2,7 @@ package cn.com.ctop.alarm.modules.service.impl;
 
 import cn.com.ctop.alarm.modules.constant.MatchLogic;
 import cn.com.ctop.alarm.modules.entity.AlarmEventSend;
+import cn.com.ctop.alarm.modules.entity.AlarmRuleOperationRecord;
 import cn.com.ctop.alarm.modules.entity.AlarmRuleRecord;
 import cn.com.ctop.alarm.modules.entity.RuleAccountTemplate;
 import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
@@ -11,12 +12,14 @@ import cn.com.ctop.alarm.modules.entity.RuleIndicator;
 import cn.com.ctop.alarm.modules.entity.RuleTemplate;
 import cn.com.ctop.alarm.modules.enums.ConditEnum;
 import cn.com.ctop.alarm.modules.mapper.AlarmEventSendMapper;
+import cn.com.ctop.alarm.modules.mapper.AlarmRuleOperationRecordMapper;
 import cn.com.ctop.alarm.modules.mapper.RuleAccountTemplateMapper;
 import cn.com.ctop.alarm.modules.mapper.RuleAccountThresholdMapper;
 import cn.com.ctop.alarm.modules.mapper.RuleBaseMapper;
 import cn.com.ctop.alarm.modules.mapper.RuleGroupMapper;
 import cn.com.ctop.alarm.modules.mapper.RuleIndicatorMapper;
 import cn.com.ctop.alarm.modules.mapper.RuleTemplateMapper;
+import cn.com.ctop.alarm.modules.service.ExternalLinkService;
 import cn.com.ctop.alarm.modules.service.IAlarmRuleRecordService;
 import cn.com.ctop.alarm.modules.service.IRuleAccountTemplateService;
 import cn.com.ctop.alarm.modules.service.IRuleGroupService;
@@ -30,7 +33,12 @@ import cn.com.ctop.common.module.service.IRuleDataAccountService;
 import cn.com.ctop.common.module.service.ISendMessageService;
 import cn.com.ctop.common.module.utils.Check;
 import cn.com.ctop.common.module.utils.SendMailUtil;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroupBid;
+import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouGroupBidMapper;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
+import cn.com.ctop.toutiao.modules.material.entity.ByteDanceAdvertisePlan;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceCreativeService;
 import com.alibaba.fastjson.JSONArray;
@@ -39,9 +47,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xxl.job.core.enums.NoEn;
 import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.util.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -63,6 +75,11 @@ import java.util.concurrent.Executors;
 @Service
 public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup> implements IRuleGroupService {
 
+    //修改头条CPABID出价,投放时间
+    private static final String URL_UPDATE_CPABID = "";
+    //修改头条预算
+    private static final String URL_UPDATE_BUDGET = "";
+
     @Autowired
     private RuleBaseMapper ruleBaseMapper;
     @Autowired
@@ -101,6 +118,14 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
     private IAlarmRuleRecordService alarmRuleRecordService;
     @Autowired
     private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IKuaiShouGroupService kuaiShouGroupService;
+    @Resource
+    private KuaiShouGroupBidMapper groupBidMapper;
+    @Resource
+    private AlarmRuleOperationRecordMapper ruleOperationRecordMapper;
+    @Resource
+    private ExternalLinkService externalLinkService;
 
     private JSONObject userObj = null;
     private final static String ACCOUNT = "account";
@@ -197,7 +222,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         } else {
             matchData = getRuleData(templates.getAccountId(), "KS");
         }
-        if (Check.isNull(matchData)) {
+        if (Check.isNull(matchData) || matchData.isEmpty()) {
             log.warn("获取匹配数据失败");
             return;
         }
@@ -247,64 +272,516 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         for (RuleGroup ruleGroup : ruleGroups) {
             JSONArray complianceList = new JSONArray();
             List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
+            if (Check.isNull(ruleBaseList)) {
+                continue;
+            }
             //存储触发预警的数据
             List<AlarmRuleRecord> recordList = new ArrayList<>();
-            if (Check.isNull(ruleBaseList)) {
+            //是否有后续操作
+            Integer operation = ruleGroup.getOperation();
+            if (!Check.isNull(operation) && operation == 1) {
+                //有后续操作
+                checkRuleGroupsForOperation(isCopy, thresholdObj, ruleGroup, indicators, matchData, complianceList, type, ruleBaseList, accountName);
+            } else {
+                //复制逻辑
+                if (isCopy) {
+                    JSONObject batchNo = thresholdObj.getJSONObject(ruleGroup.getId().toString());
+                    for (Map.Entry<String, Object> entry : batchNo.entrySet()) {
+                        JSONObject thresholdJn = (JSONObject) entry.getValue();
+                        if (!Check.isNull(thresholdJn)) {
+                            CombinationRule(ruleGroup, thresholdJn, indicators, matchData, complianceList, type, recordList);
+                        }
+                    }
+                } else {
+                    boolean isGroup = "group".equals(ruleGroup.getRuleType());
+                    //匹配组合规则
+                    if (isGroup) {
+                        CombinationRule(ruleGroup, thresholdObj, indicators, matchData, complianceList, type, recordList);
+                        //匹配单规则
+                    } else {
+                        RuleBase ruleBase = ruleBaseList.get(0);
+                        if (Check.isNull(ruleBase)) {
+                            continue;
+                        }
+                        //指标对象
+                        JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
+                        //阈值对象
+                        JSONObject thresholdJson = thresholdObj.getJSONObject(ruleBase.getId().toString());
+                        if (Check.isNull(thresholdJson) || thresholdJson.isEmpty()) {
+                            continue;
+                        }
+                        //阈值
+                        String threshold = thresholdJson.getString("threshold");
+                        //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
+                        if (Check.isNull(threshold) || threshold.contains("unlimited")) {
+                            continue;
+                        }
+                        //维度数据
+                        JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
+                        if (!Check.isNull(dimensionData)) {
+                            for (int i = 0; i < dimensionData.size(); i++) {
+                                JSONObject obj = dimensionData.getJSONObject(i);
+                                String value = obj.getString(ruleBase.getIndicatorCode());
+                                if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, obj, ruleBase.getIndicatorCode())) {
+                                    alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, threshold, recordList);
+                                    complianceList.add(obj);
+                                }
+                            }
+                        }
+                    }
+                }
+                if (!Check.isNull(complianceList)) {
+                    getAndSendMessag(complianceList, ruleGroup, accountName, type, false);
+                    Thread thread = new Thread() {
+                        @Override
+                        public void run() {
+                            alarmRuleRecordService.saveBatch(recordList);
+                        }
+                    };
+                    thread.start();
+                }
+            }
+        }
+    }
+
+    /**
+     * B 含操作的规则匹配逻辑
+     */
+    private void checkRuleGroupsForOperation(boolean isCopy, JSONObject thresholdObj, RuleGroup ruleGroup, JSONObject indicators, JSONObject matchData, JSONArray complianceList, Integer type, List<RuleBase> ruleBaseList, String accountName) {
+        //存储触发预警的数据
+        List<AlarmRuleRecord> recordList = new ArrayList<>();
+        String indicatorCode = "";
+        //复制逻辑
+        if (isCopy) {
+            JSONObject batchNo = thresholdObj.getJSONObject(ruleGroup.getId().toString());
+            for (Map.Entry<String, Object> entry : batchNo.entrySet()) {
+                JSONObject thresholdJn = (JSONObject) entry.getValue();
+                if (!Check.isNull(thresholdJn)) {
+                    CombinationRule(ruleGroup, thresholdJn, indicators, matchData, complianceList, type, recordList);
+                }
+            }
+        } else {
+            boolean isGroup = "group".equals(ruleGroup.getRuleType());
+            //匹配组合规则
+            if (isGroup) {
+                CombinationRule(ruleGroup, thresholdObj, indicators, matchData, complianceList, type, recordList);
+                //匹配单规则
+            } else {
+                RuleBase ruleBase = ruleBaseList.get(0);
+                if (Check.isNull(ruleBase)) {
+                    return;
+                }
+                indicatorCode = ruleBase.getIndicatorCode();
+                //比较指标
+                String cindicatorCode = ruleBase.getCindicatorCode();
+                //指标对象
+                JSONObject indicator = indicators.getJSONObject(indicatorCode);
+                //阈值对象
+                JSONObject thresholdJson = thresholdObj.getJSONObject(ruleBase.getId().toString());
+                if (Check.isNull(thresholdJson) || thresholdJson.isEmpty()) {
+                    return;
+                }
+                //阈值
+                String threshold = thresholdJson.getString("threshold");
+                //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
+                if (Check.isNull(threshold) || threshold.contains("unlimited")) {
+                    return;
+                }
+                //维度数据
+                JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
+                if (!Check.isNull(dimensionData)) {
+                    for (int i = 0; i < dimensionData.size(); i++) {
+                        JSONObject obj = dimensionData.getJSONObject(i);
+                        String value = obj.getString(indicatorCode);
+                        String othreshold = "";
+                        if (threshold.contains("~")) {
+                            othreshold = threshold;
+                        } else {
+                            othreshold = getThresholdForOperation(obj, ruleBase, threshold, type);
+                        }
+                        if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), othreshold, value, obj, ruleBase.getIndicatorCode())) {
+                            alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, othreshold, recordList);
+                            obj.put("thresholdJson", thresholdJson);
+                            complianceList.add(obj);
+                        }
+                    }
+                }
+            }
+        }
+        if (!Check.isNull(complianceList)) {
+            performOperation(ruleGroup, complianceList, type, accountName);
+            Thread thread = new Thread() {
+                @Override
+                public void run() {
+                    alarmRuleRecordService.saveBatch(recordList);
+                }
+            };
+            thread.start();
+        }
+    }
+
+    /**
+     * 获取操作阈值
+     */
+    private String getThresholdForOperation(JSONObject obj, RuleBase ruleBase, String threshold, Integer type) {
+        String othreshold = "";
+        Long accountId = obj.getLong("accountId");
+        //比较指标
+        String cindicatorCode = ruleBase.getCindicatorCode();
+        String indicatorCode = ruleBase.getIndicatorCode();
+        if (type == 1 || type == 3) {
+            //头条
+            Long planId = obj.getLong("planId");
+            ByteDanceAdvertisePlan byteDancePlan = byteDanceAdvertisePlanService.getById(planId);
+            if ("bid".equals(cindicatorCode)) {
+                BigDecimal bid = byteDancePlan.getBid();
+                if ("PRICING_OCPC".equals(byteDancePlan.getPricing()) || "PRICING_OCPM".equals(byteDancePlan.getPricing())) {
+                    bid = byteDancePlan.getCpaBid();
+                }
+                //转化成本
+                if ("convertCost".equals(indicatorCode)) {
+                    //倍数计算, 转化成本 高于or低于当前倍数时,预警
+                    othreshold = bid.multiply(new BigDecimal(threshold)).toString();
+                }
+            } else {
+                othreshold = threshold;
+            }
+            if ("dayBudget".equals(cindicatorCode)) {
+                if ("cost".equals(indicatorCode)) {
+                    //倍数计算, 转化成本 高于or低于当前倍数时,预警
+                    threshold = new BigDecimal(String.valueOf(byteDancePlan.getBudget())).multiply(new BigDecimal(threshold)).toString();
+                }
+            } else {
+                othreshold = threshold;
+            }
+        } else {
+            //快手
+            Long unitId = obj.getLong("unitId");
+            KuaiShouGroup kuaiShouGroup = kuaiShouGroupService.selectGroupByUnitId(accountId, unitId);
+            if ("bid".equals(cindicatorCode)) {
+                Long bid = kuaiShouGroup.getBid();
+                if (kuaiShouGroup.getBidType() == 10) {
+                    bid = kuaiShouGroup.getCpaBid();
+                }
+                //转化成本
+                if ("convertCost".equals(indicatorCode)) {
+                    //倍数计算, 转化成本 高于or低于当前倍数时,预警
+                    othreshold = new BigDecimal(String.valueOf(bid)).multiply(new BigDecimal(threshold)).toString();
+                }
+            } else {
+                othreshold = threshold;
+            }
+            if ("dayBudget".equals(cindicatorCode)) {
+                if ("charge".equals(indicatorCode)) {
+                    //倍数计算, 转化成本 高于or低于当前倍数时,预警
+                    othreshold = new BigDecimal(String.valueOf(kuaiShouGroup.getDayBudget())).multiply(new BigDecimal(threshold)).toString();
+                }
+            } else {
+                othreshold = threshold;
+            }
+        }
+        return othreshold;
+    }
+
+    /**
+     * 执行操作
+     */
+    private void performOperation(RuleGroup ruleGroup, JSONArray complianceList, Integer type, String accountName) {
+        String operationType = ruleGroup.getOperationType();
+        String operationValue = ruleGroup.getOperationValue();
+        String operate = ruleGroup.getOperate();
+        String ruleType = ruleGroup.getRuleType();
+        Long accountId = complianceList.getJSONObject(0).getLong("accountId");
+        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
+        //已操作成功的list
+        JSONArray alreadyOperatedList = new JSONArray();
+        for (int i = 0; i < complianceList.size(); i++) {
+            JSONObject obj = complianceList.getJSONObject(i);
+            AlarmRuleOperationRecord recordEntity = null;
+            JSONObject thresholdJson = obj.getJSONObject("thresholdJson");
+            if (Check.isNull(thresholdJson) || thresholdJson.isEmpty()) {
                 continue;
             }
-            //复制逻辑
-            if (isCopy) {
-                JSONObject batchNo = thresholdObj.getJSONObject(ruleGroup.getId().toString());
-                for (Map.Entry<String, Object> entry : batchNo.entrySet()) {
-                    JSONObject thresholdJn = (JSONObject) entry.getValue();
-                    if (!Check.isNull(thresholdJn)) {
-                        CombinationRule(ruleGroup, thresholdJn, indicators, matchData, complianceList, type, recordList);
+            //后续 操作阈值
+            String operationThreshold = thresholdJson.getString("operationThreshold");
+            //峰值
+            String maxValue = Check.isNull(thresholdJson.getString("maxValue")) ? "-1" : thresholdJson.getString("maxValue");
+            String minValue = Check.isNull(thresholdJson.getString("minValue")) ? "-1" : thresholdJson.getString("minValue");
+
+            if (type == 1 || type == 3) {
+                Long planId = obj.getLong("planId");//头条
+                if (Check.isNull(planId)) {
+                    continue;
+                }
+                ByteDanceAdvertisePlan byteDancePlan = byteDanceAdvertisePlanService.getById(planId);
+                if (Check.isNull(byteDancePlan)) {
+                    continue;
+                }
+                //修改出价
+                if ("BID".equals(operate)) {
+                    BigDecimal oldBid = byteDancePlan.getBid();
+                    if ("PRICING_OCPC".equals(byteDancePlan.getPricing()) || "PRICING_OCPM".equals(byteDancePlan.getPricing())) {
+                        oldBid = byteDancePlan.getCpaBid();
+                    }
+                    if (("up".equals(operationType) && oldBid.compareTo(new BigDecimal(maxValue)) == 0) || ("down".equals(operationType) && oldBid.compareTo(new BigDecimal(minValue)) == 0)) {
+                        continue;
+                    }
+                    Long newBid = calculatedValue(oldBid, operationType, operationValue, operationThreshold, maxValue, minValue);
+                    //TODO
+                    String code = externalLinkService.editBytedancePlanCpaBidOrBudget(accountId, planId.toString(), new BigDecimal(newBid.toString()), null, null);
+                    String message = "success";
+                    if (code.equals("")) {
+                        alreadyOperatedList.add(obj);
+                    } else {
+                        message = "fail";
+                        log.error("(头条)规则引擎修改出价失败,accountId={},unitId={}", accountId, planId);
+                    }
+                    recordEntity = getOperationRecordEntity(accountId, ruleGroup, maxValue, minValue, operate, null, planId, operationThreshold, oldBid.toString(), newBid.toString(), message, "头条");
+                    //修改预算
+                } else if ("BUDGET".equals(operate)) {
+                    BigDecimal oldBudget = byteDancePlan.getBudget();
+                    if (("up".equals(operationType) && oldBudget.compareTo(new BigDecimal(maxValue)) == 0) || ("down".equals(operationType) && oldBudget.compareTo(new BigDecimal(minValue)) == 0)) {
+                        continue;
                     }
+                    Long newBudget = calculatedValue(oldBudget, operationType, operationValue, operationThreshold, maxValue, minValue);
+                    //TODO
+                    String code = externalLinkService.editBytedancePlanCpaBidOrBudget(accountId, planId.toString(), null, null, newBudget);
+                    String message = "success";
+                    if (code.equals("")) {
+                        alreadyOperatedList.add(obj);
+                    } else {
+                        message = "fail";
+                        log.error("(头条)规则引擎修改预算失败,accountId={},unitId={}", accountId, planId);
+                    }
+                    recordEntity = getOperationRecordEntity(accountId, ruleGroup, maxValue, minValue, operate, null, planId, operationThreshold, oldBudget.toString(), newBudget.toString(), message, "头条");
+                    //修改投放时间
+                } else if ("TIME".equals(operate) && !byteDancePlan.getScheduleTime().equals(operationThreshold)) {
+                    //TODO
+                    String code = externalLinkService.editBytedancePlanCpaBidOrBudget(accountId, planId.toString(), null, operationThreshold, null);
+                    String message = "success";
+                    if (code.equals("")) {
+                        alreadyOperatedList.add(obj);
+                    } else {
+                        message = "fail";
+                        log.error("规则引擎修改投放时间段失败,accountId={},unitId={}", accountId, planId);
+                    }
+                    recordEntity = getOperationRecordEntity(accountId, ruleGroup, maxValue, minValue, operate, null, planId, operationThreshold, byteDancePlan.getScheduleTime(), operationThreshold, message, "头条");
                 }
+
             } else {
-                boolean isGroup = "group".equals(ruleGroup.getRuleType());
-                //匹配组合规则
-                if (isGroup) {
-                    CombinationRule(ruleGroup, thresholdObj, indicators, matchData, complianceList, type, recordList);
-                    //匹配单规则
-                } else {
-                    RuleBase ruleBase = ruleBaseList.get(0);
-                    if (Check.isNull(ruleBase)) {
+                Long unitId = obj.getLong("unitId");//快手
+                if (Check.isNull(unitId)) {
+                    continue;
+                }
+                KuaiShouGroup kuaiShouGroup = kuaiShouGroupService.selectGroupByUnitId(accountId, unitId);
+                if (Check.isNull(kuaiShouGroup)) {
+                    continue;
+                }
+                //修改出价
+                if ("BID".equals(operate)) {
+                    Integer bidType = kuaiShouGroup.getBidType();
+                    Long oldBid = Check.isNull(kuaiShouGroup.getBid()) ? 0L : kuaiShouGroup.getBid();
+                    if (bidType == 10) {
+                        oldBid = kuaiShouGroup.getCpaBid();
+                    }
+                    if (("up".equals(operationType) && oldBid - Long.valueOf(maxValue) == 0) || ("down".equals(operationType) && oldBid - Long.valueOf(minValue) == 0)) {
                         continue;
                     }
-                    //指标对象
-                    JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
-                    //指标阈值
-                    String threshold = thresholdObj.getString(ruleBase.getId().toString());
-                    //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
-                    if (Check.isNull(threshold) || threshold.contains("unlimited")) {
+                    Long newBid = calculatedValue(new BigDecimal(oldBid.toString()), operationType, operationValue, operationThreshold, maxValue, minValue);
+                    JSONObject unitJson = new JSONObject();
+                    unitJson.put("advertiser_id", accountId);
+                    unitJson.put("unit_id", unitId);
+                    String msg = "规则引擎修改bid";
+                    if (bidType == 2) {
+                        unitJson.put("bid", newBid);
+                    } else if (bidType == 10) {
+                        unitJson.put("cpa_bid", newBid);
+                        msg = "规则引擎修改cpa_bid";
+                    }
+                    JSONObject jsonObject = kuaiShouUpdateService.updateUnit(token.getAccessToken(), unitJson);
+                    Integer code = jsonObject.getInteger("code");
+                    String message = "success";
+                    if (code == 0) {
+                        alreadyOperatedList.add(obj);
+                        //添加改价记录
+                        KuaiShouGroupBid groupBid = new KuaiShouGroupBid();
+                        groupBid.setAccountId(accountId);
+                        groupBid.setUnitId(unitId);
+                        groupBid.setBid(newBid);
+                        groupBid.setUpdateBid(oldBid);
+                        groupBid.setUserId(msg);
+                        groupBidMapper.insert(groupBid);
+                        kuaiShouGroupService.getGroupByUnitId(token.getAccessToken(), accountId, unitId);
+                    } else {
+                        message = "fail," + jsonObject.getString("message");
+                        log.error("(快手)规则引擎修改出价失败,accountId={},unitId={},{}", accountId, unitId, jsonObject.getString("message"));
+                    }
+                    recordEntity = getOperationRecordEntity(accountId, ruleGroup, maxValue, minValue, operate, unitId, null, operationThreshold, oldBid.toString(), newBid.toString(), message, "快手");
+                    //修改预算
+                } else if ("BUDGET".equals(operate)) {
+                    Long oldBudget = Check.isNull(kuaiShouGroup.getDayBudget()) ? 0L : kuaiShouGroup.getDayBudget();
+                    if (("up".equals(operationType) && oldBudget - Long.valueOf(maxValue) == 0) || ("down".equals(operationType) && oldBudget - Long.valueOf(minValue) == 0)) {
                         continue;
                     }
-                    //维度数据
-                    JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
-                    if (!Check.isNull(dimensionData)) {
-                        for (int i = 0; i < dimensionData.size(); i++) {
-                            JSONObject obj = dimensionData.getJSONObject(i);
-                            String value = obj.getString(ruleBase.getIndicatorCode());
-                            if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, obj, ruleBase.getIndicatorCode())) {
-                                alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, threshold, recordList);
-                                complianceList.add(obj);
-                            }
-                        }
+                    Long newBudget = calculatedValue(new BigDecimal(oldBudget.toString()), operationType, operationValue, operationThreshold, maxValue, minValue);
+                    Map<String, Object> updateMap = kuaiShouUpdateService.updateUnitDayBudget(token.getAccessToken(), accountId, unitId, newBudget, "规则引擎修改预算");
+                    String message = "success";
+                    if ((Integer) updateMap.get("code") == 0) {
+                        alreadyOperatedList.add(obj);
+                        kuaiShouGroupService.getGroupByUnitId(token.getAccessToken(), accountId, unitId);
+                    } else {
+                        message = "fail," + updateMap.get("message");
+                        log.error("(快手)规则引擎修改预算失败,accountId={},unitId={},{}", accountId, unitId, updateMap.get("message"));
+                    }
+                    recordEntity = getOperationRecordEntity(accountId, ruleGroup, maxValue, minValue, operate, unitId, null, operationThreshold, oldBudget.toString(), newBudget.toString(), message, "快手");
+                    //修改投放时间
+                } else if ("TIME".equals(operate)) {
+                    String newScheduleTime = getNewScheduleTime(operationThreshold);
+                    JSONObject unitJson = new JSONObject();
+                    unitJson.put("advertiser_id", accountId);
+                    unitJson.put("unit_id", unitId);
+                    unitJson.put("schedule_time", newScheduleTime);
+                    JSONObject jsonObject = kuaiShouUpdateService.updateUnit(token.getAccessToken(), unitJson);
+                    Integer code = jsonObject.getInteger("code");
+                    String message = "success";
+                    if (code == 0) {
+                        alreadyOperatedList.add(obj);
+                        kuaiShouGroupService.getGroupByUnitId(token.getAccessToken(), accountId, unitId);
+                    } else {
+                        message = "fail," + jsonObject.getString("message");
+                        log.error("(快手)规则引擎修改投放时间段失败,accountId={},unitId={},{}", accountId, unitId, jsonObject.getString("message"));
                     }
+                    recordEntity = getOperationRecordEntity(accountId, ruleGroup, maxValue, minValue, operate, unitId, null, newScheduleTime, kuaiShouGroup.getScheduleTime(), operationThreshold, message, "快手");
                 }
             }
-            if (!Check.isNull(complianceList)) {
-                getAndSendMessag(complianceList, ruleGroup, accountName, type);
-                Thread thread = new Thread() {
-                    @Override
-                    public void run() {
-                        alarmRuleRecordService.saveBatch(recordList);
-                    }
-                };
-                thread.start();
+            if (!Check.isNull(recordEntity)) {
+                ruleOperationRecordMapper.insert(recordEntity);
+            }
+        }
+        if (alreadyOperatedList.size() > 0) {
+            getAndSendMessag(alreadyOperatedList, ruleGroup, accountName, type, true);
+        }
+    }
+
+    /**
+     * 获取新的投放时间
+     */
+    private static String getNewScheduleTime(String operationThreshold) {
+        String ScheduleTime = "";
+        String WeekStr = DateUtils.getWhatDay(new Date().getTime());
+        Integer weekInt = -1;
+        switch (WeekStr) {
+            case "星期一":
+                weekInt = 0;
+                break;
+            case "星期二":
+                weekInt = 1;
+                break;
+            case "星期三":
+                weekInt = 2;
+                break;
+            case "星期四":
+                weekInt = 3;
+                break;
+            case "星期五":
+                weekInt = 4;
+                break;
+            case "星期六":
+                weekInt = 5;
+                break;
+            default:
+                weekInt = 6;
+                break;
+        }
+        //获取当前小时
+        Integer nowHour = -1;
+        try {
+            nowHour = DateUtils.getNowHour();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < weekInt * 24 + nowHour; i++) {
+            buf.append("1");
+        }
+        Integer invalidTime = Integer.valueOf(operationThreshold);
+        for (int i = 0; i < invalidTime; i++) {
+            buf.append("0");
+        }
+        for (int i = 0; i < 7 * 24 - weekInt * 24 - nowHour - invalidTime; i++) {
+            buf.append("1");
+        }
+        return buf.toString();
+    }
+
+    /**
+     * 整合操作记录实体类
+     */
+    private AlarmRuleOperationRecord getOperationRecordEntity(Long accountId, RuleGroup ruleGroup, String maxValue, String minValue, String indicatorCode, Long unitId, Long planId, String operationThreshold, String oldValue, String newValue, String msg, String mediaType) {
+        AlarmRuleOperationRecord record = new AlarmRuleOperationRecord();
+        record.setAccountId(accountId);
+        record.setOperationType(ruleGroup.getOperationType());
+        record.setOperationValue(ruleGroup.getOperationValue());
+        record.setMaxValue(maxValue);
+        record.setMinValue(minValue);
+        record.setUnitId(unitId);
+        record.setPlanId(planId);
+        record.setGroupId(ruleGroup.getId());
+        record.setIndicatorCode(indicatorCode);
+        record.setBeforeValue(oldValue);
+        record.setAfterValue(newValue);
+        record.setOperationThreshold(operationThreshold);
+        record.setMediaType(mediaType);
+        record.setMessage(msg);
+        record.setValueTime(DateUtils.formatDate(new Date()));
+        return record;
+    }
+
+    /**
+     * 计算待调整数值
+     * <p>
+     * 广告组bid_type为CPC和eCPC时:不得低于0.2元,不得高于100元,单位:厘;广告组bid_type为OCPC时:行为出价不得低于1元;激活出价不得低于5元(白名单用户不得低于2元),单位:厘
+     *
+     * @param goalValue          目标值
+     * @param operationType      操作类型:up-提高,down-降低,to-调整至
+     * @param operationValue     操作内容:price-金额,percent-百分数
+     * @param operationThreshold 操作阈值
+     * @param fmaxValue          目标值的峰值
+     * @param fminValue          目标值的最低值
+     * @return
+     * @throws
+     */
+    private static Long calculatedValue(BigDecimal goal, String operationType, String operationValue, String operationThreshold, String fmaxValue, String fminValue) {
+        BigDecimal threshold = new BigDecimal(operationThreshold);
+        BigDecimal maxValue = new BigDecimal(fmaxValue);
+        BigDecimal minValue = new BigDecimal(fminValue);
+        BigDecimal value = null;
+        //操作金额
+        if ("price".equals(operationValue)) {
+            if ("up".equals(operationType)) {
+                value = goal.add(threshold);
+            } else if ("down".equals(operationType)) {
+                value = goal.subtract(threshold);
+            } else if ("to".equals(operationType)) {
+                value = threshold;
+            }
+        } else {
+            //操作百分数
+            if ("up".equals(operationType)) {
+                value = goal.add(goal.multiply(threshold));
+            } else if ("down".equals(operationType)) {
+                value = goal.subtract(goal.multiply(threshold));
+            } else if ("to".equals(operationType)) {
+                value = goal.multiply(threshold);
             }
         }
+        if (value.compareTo(maxValue) == 1) {
+            value = maxValue;
+        }
+        if (value.compareTo(minValue) == -1) {
+            value = minValue;
+        }
+        return value.longValue();
     }
 
     /**
@@ -315,7 +792,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @throws
      * @author ZHAOXA
      */
-    private void alarmRuleRecord(JSONObject obj, RuleGroup ruleGroup, RuleBase ruleBase, JSONObject indicator, Integer mediaType, String threshold, List<AlarmRuleRecord> recordList) {
+    private void alarmRuleRecord(JSONObject obj, RuleGroup ruleGroup, RuleBase ruleBase, JSONObject
+            indicator, Integer mediaType, String threshold, List<AlarmRuleRecord> recordList) {
         try {
             Long planId = obj.getLong("planId");
             Long unidId = null;
@@ -363,7 +841,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @throws
      * @author ZHAOXA
      */
-    private void CombinationRule(RuleGroup ruleGroup, JSONObject thresholdObj, JSONObject indicators, JSONObject matchData, JSONArray complianceList, Integer type, List<AlarmRuleRecord> recordList) {
+    private void CombinationRule(RuleGroup ruleGroup, JSONObject thresholdObj, JSONObject indicators, JSONObject
+            matchData, JSONArray complianceList, Integer type, List<AlarmRuleRecord> recordList) {
         List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
         //符合规则的数据集
         JSONArray groupDatas = new JSONArray();
@@ -374,8 +853,13 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         for (RuleBase ruleBase : ruleBaseList) {
             //指标对象
             JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
-            //指标阈值
-            String threshold = thresholdObj.getString(ruleBase.getId().toString());
+            //阈值对象
+            JSONObject thresholdJson = thresholdObj.getJSONObject(ruleBase.getId().toString());
+            if (Check.isNull(thresholdJson) || thresholdJson.isEmpty()) {
+                continue;
+            }
+            //阈值
+            String threshold = thresholdJson.getString("threshold");
             //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
             if (Check.isNull(threshold) || threshold.contains("unlimited")) {
                 if (!Check.isNull(accountDatas)) {
@@ -395,7 +879,9 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                 }
                 break;
             }
-            JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
+            //获取维度数据
+            String ruleDimension = ruleBase.getRuleDimension();
+            JSONArray dimensionData = matchData.getJSONArray(ruleDimension);
             if (Check.isNull(dimensionData)) {
                 if (!Check.isNull(accountDatas)) {
                     accountDatas = null;
@@ -415,7 +901,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                 break;
             }
             //账户维度数据
-            if (ACCOUNT.equals(ruleBase.getRuleDimension())) {
+            if (ACCOUNT.equals(ruleDimension)) {
                 JSONObject accountEntity = dimensionData.getJSONObject(0);
                 if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, accountEntity.getString(ruleBase.getIndicatorCode()), accountEntity, ruleBase.getIndicatorCode())) {
                     if (Check.isNull(accountDatas)) {
@@ -440,8 +926,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     }
                     break;
                 }
-            } else if (PLAN.equals(ruleBase.getRuleDimension())) {
-                planDatas = getOKData(planDatas, dimensionData, ruleBase, indicator, threshold, ruleGroup, type, recordList);
+            } else if (PLAN.equals(ruleDimension)) {
+                planDatas = getOKData(planDatas, dimensionData, ruleBase, indicator, thresholdJson, ruleGroup, type, recordList);
                 if (Check.isNull(planDatas)) {
                     if (!Check.isNull(accountDatas)) {
                         accountDatas = null;
@@ -460,8 +946,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     }
                     break;
                 }
-            } else if (CREATIVE.equals(ruleBase.getRuleDimension())) {
-                creativeDatas = getOKData(creativeDatas, dimensionData, ruleBase, indicator, threshold, ruleGroup, type, recordList);
+            } else if (CREATIVE.equals(ruleDimension)) {
+                creativeDatas = getOKData(creativeDatas, dimensionData, ruleBase, indicator, thresholdJson, ruleGroup, type, recordList);
                 if (Check.isNull(creativeDatas)) {
                     if (!Check.isNull(accountDatas)) {
                         accountDatas = null;
@@ -480,8 +966,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     }
                     break;
                 }
-            } else if ("target".equals(ruleBase.getRuleDimension())) {
-                targetDatas = getOKData(targetDatas, dimensionData, ruleBase, indicator, threshold, ruleGroup, type, recordList);
+            } else if ("target".equals(ruleDimension)) {
+                targetDatas = getOKData(targetDatas, dimensionData, ruleBase, indicator, thresholdJson, ruleGroup, type, recordList);
                 if (Check.isNull(targetDatas)) {
                     if (!Check.isNull(accountDatas)) {
                         accountDatas = null;
@@ -500,8 +986,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     }
                     break;
                 }
-            } else if (UNIT.equals(ruleBase.getRuleDimension())) {
-                groupDatas = getOKData(groupDatas, dimensionData, ruleBase, indicator, threshold, ruleGroup, type, recordList);
+            } else if (UNIT.equals(ruleDimension)) {
+                groupDatas = getOKData(groupDatas, dimensionData, ruleBase, indicator, thresholdJson, ruleGroup, type, recordList);
                 if (Check.isNull(groupDatas)) {
                     if (!Check.isNull(accountDatas)) {
                         accountDatas = null;
@@ -544,14 +1030,25 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @throws
      * @author ZHAOXA
      */
-    private JSONArray getOKData(JSONArray ruleDatas, JSONArray dimensionData, RuleBase ruleBase, JSONObject indicator, String threshold, RuleGroup ruleGroup, Integer type, List<AlarmRuleRecord> recordList) {
+    private JSONArray getOKData(JSONArray ruleDatas, JSONArray dimensionData, RuleBase ruleBase, JSONObject
+            indicator, JSONObject thresholdJson, RuleGroup ruleGroup, Integer type, List<AlarmRuleRecord> recordList) {
+        String threshold = thresholdJson.getString("threshold");
         if (!Check.isNull(ruleDatas)) {
             JSONArray okData = new JSONArray();
             for (int i = 0; i < ruleDatas.size(); i++) {
                 JSONObject obj = ruleDatas.getJSONObject(i);
                 String value = obj.getString(ruleBase.getIndicatorCode());
-                if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, obj, ruleBase.getIndicatorCode())) {
-                    alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, threshold, recordList);
+                String othreshold = "";
+                if (threshold.contains("~")) {
+                    othreshold = threshold;
+                } else {
+                    othreshold = getThresholdForOperation(obj, ruleBase, threshold, type);
+                }
+                if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), othreshold, value, obj, ruleBase.getIndicatorCode())) {
+                    alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, othreshold, recordList);
+                    if (groupThresholdFromIndicator(thresholdJson, ruleGroup.getOperate())) {
+                        obj.put("thresholdJson", thresholdJson);
+                    }
                     okData.add(obj);
                 }
             }
@@ -560,15 +1057,48 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         for (int i = 0; i < dimensionData.size(); i++) {
             JSONObject obj = dimensionData.getJSONObject(i);
             String value = obj.getString(ruleBase.getIndicatorCode());
-            if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, obj, ruleBase.getIndicatorCode())) {
-                alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, threshold, recordList);
+            String othreshold = "";
+            if (threshold.contains("~")) {
+                othreshold = threshold;
+            } else {
+                othreshold = getThresholdForOperation(obj, ruleBase, threshold, type);
+            }
+            if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), othreshold, value, obj, ruleBase.getIndicatorCode())) {
+                alarmRuleRecord(obj, ruleGroup, ruleBase, indicator, type, othreshold, recordList);
+                if (groupThresholdFromIndicator(thresholdJson, ruleGroup.getOperate())) {
+                    obj.put("thresholdJson", thresholdJson);
+                }
                 ruleDatas.add(obj);
             }
         }
         return ruleDatas;
     }
 
-    private void getAndSendMessag(JSONArray complianceList, RuleGroup ruleGroup, String accountName, Integer mediaType) {
+    private boolean groupThresholdFromIndicator(JSONObject thresholdJson, String operate) {
+        if ("SEND".equals(operate) || "PAUSE".equals(operate)) {
+            return false;
+        }
+        RuleBase base = ruleBaseMapper.selectById(thresholdJson.getLong("ruleId"));
+        String code = base.getIndicatorCode();
+        if ("BID".equals(operate)) {
+            return "charge".equals(code) || "cost".equals(code);
+        } else if ("BUDGET".equals(operate)) {
+            return "convertCost".equals(code);
+        } else if ("TIME".equals(operate)) {
+            return "scheduleTime".equals(code);
+        }
+        return false;
+    }
+
+    /**
+     * @param complianceList 触发规则数据
+     * @param ruleGroup      触发的规则组
+     * @param accountName    账户名称
+     * @param mediaType      媒体类型
+     * @param isOperation    是否有后续操作(仅做发送内容变更)
+     * @throws
+     */
+    private void getAndSendMessag(JSONArray complianceList, RuleGroup ruleGroup, String accountName, Integer mediaType, boolean isOperation) {
         Long accountId = complianceList.getJSONObject(0).getLong("accountId");
         if (Check.isNull(accountId)) {
             return;
@@ -592,7 +1122,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                         isNullCreativeJoiner.add(obj.getString("creativeId"));
                     } else {
                         String message = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, isNullCreativeJoiner.toString(), isNull);
-                        sendMsg(message, ruleGroup, user, CREATIVE, isNullCreativeJoiner.toString(), accountId, mediaType);
+                        sendMsg(message, ruleGroup, user, CREATIVE, isNullCreativeJoiner.toString(), accountId, mediaType, isOperation);
                         isNullCreativeJoiner = new StringJoiner(",");
                         isNullCreativeJoiner.add(obj.getString("creativeId"));
                     }
@@ -601,13 +1131,13 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                         isNullPlanJoiner.add(obj.getString("planId"));
                     } else {
                         String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, isNullPlanJoiner.toString(), isNull);
-                        sendMsg(msg, ruleGroup, user, PLAN, isNullPlanJoiner.toString(), accountId, mediaType);
+                        sendMsg(msg, ruleGroup, user, PLAN, isNullPlanJoiner.toString(), accountId, mediaType, isOperation);
                         isNullPlanJoiner = new StringJoiner(",");
                         isNullPlanJoiner.add(obj.getString("planId"));
                     }
                 } else {
                     String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, null, null, isNull);
-                    sendMsg(msg, ruleGroup, user, ACCOUNT, null, accountId, mediaType);
+                    sendMsg(msg, ruleGroup, user, ACCOUNT, null, accountId, mediaType, isOperation);
                 }
             } else {
                 if (!Check.isNull(obj.getString("creativeId"))) {
@@ -616,7 +1146,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                         creativeJoiner.add(obj.getString("creativeId"));
                     } else {
                         String message = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, creativeJoiner.toString(), isNull);
-                        sendMsg(message, ruleGroup, user, CREATIVE, creativeJoiner.toString(), accountId, mediaType);
+                        sendMsg(message, ruleGroup, user, CREATIVE, creativeJoiner.toString(), accountId, mediaType, isOperation);
                         creativeJoiner = new StringJoiner(",");
                         creativeJoiner.add(obj.getString("creativeId"));
                     }
@@ -625,7 +1155,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                         unitJoiner.add(obj.getString("unitId"));
                     } else {
                         String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, UNIT, unitJoiner.toString(), isNull);
-                        sendMsg(msg, ruleGroup, user, UNIT, unitJoiner.toString(), accountId, mediaType);
+                        sendMsg(msg, ruleGroup, user, UNIT, unitJoiner.toString(), accountId, mediaType, isOperation);
                         unitJoiner = new StringJoiner(",");
                         unitJoiner.add(obj.getString("unitId"));
                     }
@@ -634,35 +1164,35 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                         planJoiner.add(obj.getString("planId"));
                     } else {
                         String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, planJoiner.toString(), isNull);
-                        sendMsg(msg, ruleGroup, user, PLAN, planJoiner.toString(), accountId, mediaType);
+                        sendMsg(msg, ruleGroup, user, PLAN, planJoiner.toString(), accountId, mediaType, isOperation);
                         planJoiner = new StringJoiner(",");
                         planJoiner.add(obj.getString("planId"));
                     }
                 } else {
                     String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, null, null, isNull);
-                    sendMsg(msg, ruleGroup, user, ACCOUNT, null, accountId, mediaType);
+                    sendMsg(msg, ruleGroup, user, ACCOUNT, null, accountId, mediaType, isOperation);
                 }
             }
         }
         if (!Check.isNull(creativeJoiner.toString())) {
             String creativeMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, creativeJoiner.toString(), false);
-            sendMsg(creativeMsg, ruleGroup, user, CREATIVE, creativeJoiner.toString(), accountId, mediaType);
+            sendMsg(creativeMsg, ruleGroup, user, CREATIVE, creativeJoiner.toString(), accountId, mediaType, isOperation);
         }
         if (!Check.isNull(unitJoiner.toString())) {
             String creativeMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, UNIT, unitJoiner.toString(), false);
-            sendMsg(creativeMsg, ruleGroup, user, UNIT, unitJoiner.toString(), accountId, mediaType);
+            sendMsg(creativeMsg, ruleGroup, user, UNIT, unitJoiner.toString(), accountId, mediaType, isOperation);
         }
         if (!Check.isNull(planJoiner.toString())) {
             String planMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, planJoiner.toString(), false);
-            sendMsg(planMsg, ruleGroup, user, PLAN, planJoiner.toString(), accountId, mediaType);
+            sendMsg(planMsg, ruleGroup, user, PLAN, planJoiner.toString(), accountId, mediaType, isOperation);
         }
         if (!Check.isNull(isNullCreativeJoiner.toString())) {
             String isNullCreativeMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, isNullCreativeJoiner.toString(), true);
-            sendMsg(isNullCreativeMsg, ruleGroup, user, CREATIVE, isNullCreativeJoiner.toString(), accountId, mediaType);
+            sendMsg(isNullCreativeMsg, ruleGroup, user, CREATIVE, isNullCreativeJoiner.toString(), accountId, mediaType, isOperation);
         }
         if (!Check.isNull(isNullPlanJoiner.toString())) {
             String isNullPlanMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, isNullPlanJoiner.toString(), true);
-            sendMsg(isNullPlanMsg, ruleGroup, user, PLAN, isNullPlanJoiner.toString(), accountId, mediaType);
+            sendMsg(isNullPlanMsg, ruleGroup, user, PLAN, isNullPlanJoiner.toString(), accountId, mediaType, isOperation);
         }
     }
 
@@ -677,7 +1207,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @throws
      * @author ZHAOXA
      */
-    private void sendMsg(String msg, RuleGroup ruleGroup, JSONObject user, String type, String ids, Long accountId, Integer mediaType) {
+    private void sendMsg(String msg, RuleGroup ruleGroup, JSONObject user, String type, String ids, Long accountId, Integer mediaType, boolean isOperation) {
         try {
             boolean isPause = "PAUSE".equals(ruleGroup.getOperate());
             if (isPause) {
@@ -691,10 +1221,18 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     msg = msg.replace(",", ",");
                 }
                 if (ACCOUNT.equals(type)) {
-                    msg += "请您及时查看并调整";
+                    msg += "请您及时查看并调整";
                 }
             } else {
-                msg += "请您及时查看并调整!";
+                msg += "请您及时查看并调整";
+            }
+            if (isOperation) {
+                msg = msg.replace("请您及时查看并调整", "系统已按照设置调整出价,请您及时查看");
+                if ("BUDGET".equals(ruleGroup.getOperate())) {
+                    msg = msg.replace("出价", "预算");
+                } else if ("TIME".equals(ruleGroup.getOperate())) {
+                    msg = msg.replace("出价", "投放时间");
+                }
             }
             String sendType = ruleGroup.getSendType();
             if ("SMS".equals(sendType)) {
@@ -861,7 +1399,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                             return null;
                         }
                         for (RuleAccountThreshold threshold : thresholdList) {
-                            batchNoObj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
+                            batchNoObj.put(String.valueOf(threshold.getRuleId()), threshold);
                         }
                         groupIdObj.put(batchNo.toString(), batchNoObj);
                     }
@@ -873,7 +1411,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     return null;
                 }
                 for (RuleAccountThreshold threshold : thresholdList) {
-                    obj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
+                    obj.put(String.valueOf(threshold.getRuleId()), threshold);
                 }
             }
         } catch (Exception e) {

+ 13 - 4
module-common/src/main/java/cn/com/ctop/common/module/service/impl/RuleDataAccountKuaishouServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.ctop.common.module.mapper.RuleDataTargetKuaishouMapper;
 import cn.com.ctop.common.module.mapper.RuleDatePlanKuaishouMapper;
 import cn.com.ctop.common.module.mapper.RuleDateUnitKuaishouMapper;
 import cn.com.ctop.common.module.service.IRuleDataAccountKuaishouService;
+import cn.com.ctop.common.module.utils.Check;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xxl.job.core.enums.NoEn;
@@ -45,13 +46,21 @@ public class RuleDataAccountKuaishouServiceImpl extends ServiceImpl<RuleDataAcco
         map.put("account_id", accountId);
         map.put("status", NoEn.NO1.valueInt());
         List<RuleDataAccountKuaishou> accountList = ruleDataAccountKuaishouMapper.selectByMap(map);
-        obj.put("account", accountList);
+        if (!Check.isNull(accountList)) {
+            obj.put("account", accountList);
+        }
         List<RuleDateUnitKuaishou> unitKuaishous = ruleDateUnitKuaishouMapper.selectByMap(map);
-        obj.put("unit", unitKuaishous);
+        if (!Check.isNull(unitKuaishous)) {
+            obj.put("unit", unitKuaishous);
+        }
         List<RuleDataTargetKuaishou> targetKuaishous = ruleDataTargetKuaishouMapper.selectByMap(map);
-        obj.put("target", targetKuaishous);
+        if (!Check.isNull(targetKuaishous)) {
+            obj.put("target", targetKuaishous);
+        }
         List<RuleDatePlanKuaishou> planKuaishous = ruleDatePlanKuaishouMapper.selectByMap(map);
-        obj.put("plan", planKuaishous);
+        if (!Check.isNull(planKuaishous)) {
+            obj.put("plan", planKuaishous);
+        }
         return obj;
     }
 }

+ 13 - 4
module-common/src/main/java/cn/com/ctop/common/module/service/impl/RuleDataAccountServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.ctop.common.module.mapper.RuleDataCreativeMapper;
 import cn.com.ctop.common.module.mapper.RuleDataPlanMapper;
 import cn.com.ctop.common.module.mapper.RuleDataTargetMapper;
 import cn.com.ctop.common.module.service.IRuleDataAccountService;
+import cn.com.ctop.common.module.utils.Check;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xxl.job.core.enums.NoEn;
@@ -48,13 +49,21 @@ public class RuleDataAccountServiceImpl extends ServiceImpl<RuleDataAccountMappe
         map.put("account_id", accountId);
         map.put("status", NoEn.NO1.valueInt());
         List<RuleDataAccount> ruleDataAccounts = ruleDataAccountMapper.selectByMap(map);
-        obj.put("account", ruleDataAccounts);
+        if (!Check.isNull(ruleDataAccounts)) {
+            obj.put("account", ruleDataAccounts);
+        }
         List<RuleDataPlan> ruleDataPlans = ruleDataPlanMapper.selectByMap(map);
-        obj.put("plan", ruleDataPlans);
+        if (!Check.isNull(ruleDataPlans)) {
+            obj.put("plan", ruleDataPlans);
+        }
         List<RuleDataTarget> ruleDataTargets = ruleDataTargetMapper.selectByMap(map);
-        obj.put("target", ruleDataTargets);
+        if (!Check.isNull(ruleDataTargets)) {
+            obj.put("target", ruleDataTargets);
+        }
         List<RuleDataCreative> ruleDataCreatives = ruleDataCreativeMapper.selectByMap(map);
-        obj.put("creative", ruleDataCreatives);
+        if (!Check.isNull(ruleDataCreatives)) {
+            obj.put("creative", ruleDataCreatives);
+        }
         return obj;
     }
 }

+ 94 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/AlarmRuleRebackJob.java

@@ -0,0 +1,94 @@
+package cn.com.ctop.job.bytedance.handler;
+
+
+import cn.com.ctop.alarm.modules.entity.AlarmRuleOperationRecord;
+import cn.com.ctop.alarm.modules.mapper.AlarmRuleOperationRecordMapper;
+import cn.com.ctop.alarm.modules.service.ExternalLinkService;
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
+import com.alibaba.fastjson.JSONObject;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import org.jeecg.common.util.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Component
+public class AlarmRuleRebackJob {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private AlarmRuleOperationRecordMapper ruleOperationRecordMapper;
+    @Autowired
+    private IKuaiShouUpdateService kuaiShouUpdateService;
+    @Autowired
+    private IKuaiShouGroupService kuaiShouGroupService;
+    @Resource
+    private ExternalLinkService externalLinkService;
+
+    static ExecutorService executorKSService = Executors.newFixedThreadPool(5);
+    static ExecutorService executorTTService = Executors.newFixedThreadPool(5);
+
+    /**
+     * 每日回退修改投放时段定时任务
+     * @param
+     * @return
+     * @throws
+     * @author ZHAOXA
+     */
+    @XxlJob("alarmRuleRebackJob")
+    public void execute() throws Exception {
+        rebackKuaiShou();
+        rebackByteDance();
+    }
+
+    private void rebackKuaiShou() {
+        List<AlarmRuleOperationRecord> ruleAccountTemplates = ruleOperationRecordMapper.queryToBeRestoredInfo("快手",DateUtils.getLastDay(DateUtils.formatDate(new Date()), 1));
+        if (!Check.isNull(ruleAccountTemplates)) {
+            ruleAccountTemplates.forEach(operationRecord -> {
+                CtopOauthToken token = tokenService.getTokenByAccountId(operationRecord.getAccountId());
+                executorKSService.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        JSONObject unitJson = new JSONObject();
+                        unitJson.put("advertiser_id", operationRecord.getAccountId());
+                        unitJson.put("unit_id", operationRecord.getUnitId());
+                        unitJson.put("schedule_time", operationRecord.getBeforeValue());
+                        JSONObject jsonObject = kuaiShouUpdateService.updateUnit(token.getAccessToken(), unitJson);
+                        Integer code = jsonObject.getInteger("code");
+                        String message = "success";
+                        if (code == 0) {
+                            kuaiShouGroupService.getGroupByUnitId(token.getAccessToken(), operationRecord.getAccountId(), operationRecord.getUnitId());
+                        }
+                    }
+                });
+            });
+        }
+    }
+
+    private void rebackByteDance() {
+        List<AlarmRuleOperationRecord> ruleAccountTemplates = ruleOperationRecordMapper.queryToBeRestoredInfo("头条",DateUtils.getLastDay(DateUtils.formatDate(new Date()), 1));
+        if (!Check.isNull(ruleAccountTemplates)) {
+            ruleAccountTemplates.forEach(operationRecord -> {
+                CtopOauthToken token = tokenService.getTokenByAccountId(operationRecord.getAccountId());
+                executorTTService.submit(new Runnable() {
+                    @Override
+                    public void run() {
+                        JSONObject unitJson = new JSONObject();
+                        String code = externalLinkService.editBytedancePlanCpaBidOrBudget(operationRecord.getAccountId(), operationRecord.getPlanId().toString(), null, operationRecord.getBeforeValue(), null);
+                    }
+                });
+            });
+        }
+    }
+}

+ 39 - 0
module-job-kuaishou/src/main/java/cn/com/ctop/job/kuaishou/handler/ExploreReportJob.java

@@ -0,0 +1,39 @@
+package cn.com.ctop.job.kuaishou.handler;
+
+
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyExploreService;
+import com.xxl.job.core.context.XxlJobHelper;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Component
+@Slf4j
+public class ExploreReportJob {
+
+    @Autowired
+    private IKuaishouReportDailyExploreService exploreService;
+
+    static ExecutorService executorService = Executors.newFixedThreadPool(5);
+
+    /**
+     * 快手全量计划物料数据
+     */
+    @XxlJob("groupExploreReportJob")
+    public void execute() {
+        List<KuaishouReportDailyExplore> list = exploreService.getUnitListByStudyStatus();
+        list.forEach(group -> executorService.submit(() ->
+                exploreService.getExploreUnitReports(group.getAccountId(), group.getUnitId())
+        ));
+        XxlJobHelper.log("获取广告组加速探索报表信息");
+    }
+
+}

+ 3 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/app/mapper/KuaishouAccountBalanceBudgetMapper.java

@@ -3,6 +3,7 @@ package cn.com.ctop.kuaishou.modules.app.mapper;
 
 import cn.com.ctop.kuaishou.modules.app.entity.KuaishouAccountBalanceBudget;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 快手-账余额、预算
@@ -16,4 +17,6 @@ public interface KuaishouAccountBalanceBudgetMapper extends BaseMapper<KuaishouA
     void replace(KuaishouAccountBalanceBudget budget);
 
     void updateAllIsInvalidState();
+
+    KuaishouAccountBalanceBudget queryByAccountId(@Param("accountId") Long accountId);
 }

+ 6 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/app/mapper/xml/KuaishouAccountBalanceBudgetMapper.xml

@@ -33,4 +33,10 @@
         where 1 = 1
     </update>
 
+    <select id="queryByAccountId" resultType="cn.com.ctop.kuaishou.modules.app.entity.KuaishouAccountBalanceBudget">
+        SELECT *
+        FROM ctop_kuaishou_account_balance_budget
+        WHERE account_id = #{accountId}
+    </select>
+
 </mapper>

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

@@ -608,8 +608,6 @@ public class KuaiShouUpdateServiceImpl implements IKuaiShouUpdateService {
             Map<String, String> headers = new HashMap<>();
             headers.put("Access-Token", accessToken);
             headers.put("Content-Type", "application/json");
-            System.err.println("修改广告组入参:" + unitJson);
-            System.err.println("修改广告组head:" + headers);
             String result = HttpUtils.kuaiShouhttpPostRequest(url, unitJson.toJSONString(), headers);
             JSONObject resultJson = JSONObject.parseObject(result);
             log.info("修改广告组返回信息:{}", resultJson);

+ 36 - 23
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/controller/KuaishouGroupExploreController.java

@@ -1,3 +1,4 @@
+
 package cn.com.ctop.kuaishou.modules.report.controller;
 
 import cn.com.ctop.common.module.utils.QueryGenerator;
@@ -11,11 +12,19 @@ import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.api.vo.Result;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
 import javax.servlet.http.HttpServletRequest;
 import java.util.Arrays;
 
+
 /**
  * 广告组的加速探索报表
  *
@@ -23,14 +32,16 @@ import java.util.Arrays;
  * @version V1.0
  * @date 2021-02-02
  */
+
 @Slf4j
 @Api(tags = "广告组的加速探索报表")
 @RestController
-@RequestMapping("/explore")
+@RequestMapping("/explores")
 public class KuaishouGroupExploreController {
     @Autowired
     private IKuaishouGroupExploreService kuaishouGroupExploreService;
 
+
     /**
      * 分页列表查询
      *
@@ -40,6 +51,7 @@ public class KuaishouGroupExploreController {
      * @param req
      * @return
      */
+
     @GetMapping(value = "/list")
     public Result<IPage<KuaishouGroupExplore>> queryPageList(KuaishouGroupExplore kuaishouGroupExplore,
                                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@@ -54,76 +66,71 @@ public class KuaishouGroupExploreController {
         return result;
     }
 
+
     /**
      * 查询加速探索信息接口
      *
      * @param data
      * @return
      */
+
     @PostMapping(value = "/unitExploreInfoGet")
     public Result<Object> unitExploreInfoGet(@RequestBody JSONObject data) {
         try {
-            return kuaishouGroupExploreService.unitExploreInfoGet(data);
+            return kuaishouGroupExploreService.unitExploreInfoGet(data.getLong("accountId"), data.getLong("unitId"));
         } catch (Exception e) {
             log.error(e.getMessage(), e);
             return Result.error("操作失败");
         }
     }
 
-    /**
-     * 广告组的加速探索预算设置接口
-     *
-     * @param data
-     * @return
-     */
+
     @PostMapping(value = "/unitExploreBudgetUpdate")
     public Result<Object> unitExploreBudgetUpdate(@RequestBody JSONObject data) {
         try {
-            return kuaishouGroupExploreService.unitExploreBudgetUpdate(data);
+            return kuaishouGroupExploreService.unitExploreBudgetUpdate(data.getLong("accountId"), data.getLong("unitId"), data.getLong("exploreBudget"));
         } catch (Exception e) {
             log.error(e.getMessage(), e);
             return Result.error("操作失败");
         }
     }
 
-    /**
-     * 暂停广告组的加速探索预算接口
-     *
-     * @param data
-     * @return
-     */
-    @PostMapping(value = "/unitExploreStatusPause")
-    public Result<Object> unitExploreStatusPause(@RequestBody JSONObject data) {
+    @PostMapping(value = "/querySpeedExploreReport")
+    public Result<Object> querySpeedExploreReport(@RequestBody JSONObject data) {
         try {
-            return kuaishouGroupExploreService.unitExploreStatusPause(data);
+            return kuaishouGroupExploreService.querySpeedExploreReport(data.getLong("accountId"), data.getLong("unitId"), data.getInteger("exploreBudget"), data.getLong("max_explore_budget"));
         } catch (Exception e) {
             log.error(e.getMessage(), e);
             return Result.error("操作失败");
         }
     }
 
+
     /**
-     * 查询广告组的加速探索报表接口
+     * 暂停广告组的加速探索预算接口
      *
      * @param data
      * @return
      */
-    @PostMapping(value = "/querySpeedExploreReport")
-    public Result<Object> querySpeedExploreReport(@RequestBody JSONObject data) {
+
+    @PostMapping(value = "/unitExploreStatusPause")
+    public Result<Object> unitExploreStatusPause(@RequestBody JSONObject data) {
         try {
-            return kuaishouGroupExploreService.querySpeedExploreReport(data);
+            return kuaishouGroupExploreService.unitExploreStatusPause(data);
         } catch (Exception e) {
             log.error(e.getMessage(), e);
             return Result.error("操作失败");
         }
     }
 
+
     /**
      * 辅助探索
      *
      * @param data
      * @return
      */
+
     @PostMapping(value = "/adUnitExploreSupport")
     public Result<Object> adUnitExploreSupport(@RequestBody JSONObject data) {
         try {
@@ -141,6 +148,7 @@ public class KuaishouGroupExploreController {
      * @param kuaishouGroupExplore
      * @return
      */
+
     @PostMapping(value = "/add")
     public Result<KuaishouGroupExplore> add(@RequestBody KuaishouGroupExplore kuaishouGroupExplore) {
         Result<KuaishouGroupExplore> result = new Result<>();
@@ -160,6 +168,7 @@ public class KuaishouGroupExploreController {
      * @param kuaishouGroupExplore
      * @return
      */
+
     @PutMapping(value = "/edit")
     public Result<KuaishouGroupExplore> edit(@RequestBody KuaishouGroupExplore kuaishouGroupExplore) {
         Result<KuaishouGroupExplore> result = new Result<KuaishouGroupExplore>();
@@ -176,12 +185,14 @@ public class KuaishouGroupExploreController {
         return result;
     }
 
+
     /**
      * 通过id删除
      *
      * @param id
      * @return
      */
+
     @DeleteMapping(value = "/delete")
     public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
         try {
@@ -199,6 +210,7 @@ public class KuaishouGroupExploreController {
      * @param ids
      * @return
      */
+
     @DeleteMapping(value = "/deleteBatch")
     public Result<KuaishouGroupExplore> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
         Result<KuaishouGroupExplore> result = new Result<>();
@@ -217,6 +229,7 @@ public class KuaishouGroupExploreController {
      * @param id
      * @return
      */
+
     @GetMapping(value = "/queryById")
     public Result<KuaishouGroupExplore> queryById(@RequestParam(name = "id", required = true) String id) {
         Result<KuaishouGroupExplore> result = new Result<>();

+ 275 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/controller/KuaishouReportDailyExploreController.java

@@ -0,0 +1,275 @@
+package cn.com.ctop.kuaishou.modules.report.controller;
+
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.common.module.utils.QueryGenerator;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyExploreService;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+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.oConvertUtils;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 广告组加速探索报表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-08-18
+ */
+@Slf4j
+@Api(tags = "广告组加速探索报表")
+@RestController
+@RequestMapping("/explore")
+public class KuaishouReportDailyExploreController {
+    @Autowired
+    private IKuaishouReportDailyExploreService kuaishouReportDailyExploreService;
+
+    /**
+     * 查询当日广告组数据
+     */
+    @PostMapping(value = "/todaylist")
+    public Result<Object> todaylist(@RequestBody JSONObject request) {
+        try {
+            return kuaishouReportDailyExploreService.todaylist(request);
+        } catch (Exception e) {
+            log.error("查询异常,", e.getMessage());
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
+
+    /**
+     * 查询加上探索历史
+     */
+    @PostMapping(value = "/historyList")
+    public Result<Object> historyList(@RequestBody JSONObject request) {
+        try {
+            return kuaishouReportDailyExploreService.historyList(request);
+        } catch (Exception e) {
+            log.error("查询异常,", e.getMessage());
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
+
+
+    /**
+     * 批量开启
+     */
+    @PostMapping(value = "/openBudgets")
+    public Result<Object> openBudgets(@RequestBody JSONObject request) {
+        try {
+            JSONArray unitIds = request.getJSONArray("unitIds");
+            Long accountId = request.getLong("accountId");
+            Long exploreBudget = request.getLong("exploreBudget");
+            if (Check.isNull(accountId) || Check.isNull(exploreBudget)) {
+                return Result.error("缺少参数");
+            }
+            return kuaishouReportDailyExploreService.openBudgets(accountId, unitIds, exploreBudget);
+        } catch (Exception e) {
+            log.error("查询异常,", e.getMessage());
+            e.printStackTrace();
+        }
+        return Result.error("查询失败");
+    }
+
+    /**
+     * 添加
+     *
+     * @param kuaishouReportDailyExplore
+     * @return
+     */
+    @ApiOperation(value = "广告组加速探索报表-添加", notes = "广告组加速探索报表-添加")
+    @PostMapping(value = "/add")
+    public Result<KuaishouReportDailyExplore> add(@RequestBody KuaishouReportDailyExplore kuaishouReportDailyExplore) {
+        Result<KuaishouReportDailyExplore> result = new Result<>();
+        try {
+            kuaishouReportDailyExploreService.save(kuaishouReportDailyExplore);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     * 编辑
+     *
+     * @param kuaishouReportDailyExplore
+     * @return
+     */
+    @ApiOperation(value = "广告组加速探索报表-编辑", notes = "广告组加速探索报表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<KuaishouReportDailyExplore> edit(@RequestBody KuaishouReportDailyExplore kuaishouReportDailyExplore) {
+        Result<KuaishouReportDailyExplore> result = new Result<KuaishouReportDailyExplore>();
+        KuaishouReportDailyExplore kuaishouReportDailyExploreEntity = kuaishouReportDailyExploreService.getById(kuaishouReportDailyExplore.getId());
+        if (kuaishouReportDailyExploreEntity == null) {
+            result.error500("未找到对应实体");
+        } else {
+            boolean ok = kuaishouReportDailyExploreService.updateById(kuaishouReportDailyExplore);
+            if (ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "广告组加速探索报表-通过id删除", notes = "广告组加速探索报表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name = "id") String id) {
+        try {
+            kuaishouReportDailyExploreService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败", e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     * 批量删除
+     *
+     * @param ids
+     * @return
+     */
+    @ApiOperation(value = "广告组加速探索报表-批量删除", notes = "广告组加速探索报表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<KuaishouReportDailyExplore> deleteBatch(@RequestParam(name = "ids") String ids) {
+        Result<KuaishouReportDailyExplore> result = new Result<>();
+        if (ids == null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        } else {
+            this.kuaishouReportDailyExploreService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     *
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "广告组加速探索报表-通过id查询", notes = "广告组加速探索报表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<KuaishouReportDailyExplore> queryById(@RequestParam(name = "id", required = true) String id) {
+        Result<KuaishouReportDailyExplore> result = new Result<>();
+        KuaishouReportDailyExplore kuaishouReportDailyExplore = kuaishouReportDailyExploreService.getById(id);
+        if (kuaishouReportDailyExplore == null) {
+            result.error500("未找到对应实体");
+        } else {
+            result.setResult(kuaishouReportDailyExplore);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<KuaishouReportDailyExplore> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                KuaishouReportDailyExplore kuaishouReportDailyExplore = JSON.parseObject(deString, KuaishouReportDailyExplore.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(kuaishouReportDailyExplore, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<KuaishouReportDailyExplore> pageList = kuaishouReportDailyExploreService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "广告组加速探索报表列表");
+        mv.addObject(NormalExcelConstants.CLASS, KuaishouReportDailyExplore.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("广告组加速探索报表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<KuaishouReportDailyExplore> listKuaishouReportDailyExplores = ExcelImportUtil.importExcel(file.getInputStream(), KuaishouReportDailyExplore.class, params);
+                kuaishouReportDailyExploreService.saveBatch(listKuaishouReportDailyExplores);
+                return Result.ok("文件导入成功!数据行数:" + listKuaishouReportDailyExplores.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+                return Result.error("文件导入失败:" + e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+
+}

+ 141 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/entity/KuaishouReportDailyExplore.java

@@ -0,0 +1,141 @@
+package cn.com.ctop.kuaishou.modules.report.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 广告组加速探索报表
+ *
+ * @author jeecg-boot
+ * @version V1.0
+ * @date 2021-08-18
+ */
+@Data
+@TableName("ctop_kuaishou_report_daily_explore")
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value = "ctop_kuaishou_report_daily_explore对象", description = "广告组加速探索报表")
+public class KuaishouReportDailyExplore {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+    /**
+     * 账户ID
+     */
+    @Excel(name = "账户ID", width = 15)
+    @ApiModelProperty(value = "账户ID")
+    private Long accountId;
+    /**
+     * 计划ID
+     */
+    @Excel(name = "计划ID", width = 15)
+    @ApiModelProperty(value = "计划ID")
+    private Long campaignId;
+    /**
+     * 组ID
+     */
+    @Excel(name = "组ID", width = 15)
+    @ApiModelProperty(value = "组ID")
+    private Long unitId;
+    /**
+     * 组名称
+     */
+    @Excel(name = "组名称", width = 15)
+    @ApiModelProperty(value = "组名称")
+    private String unitName;
+    /**
+     * 探索预算
+     */
+    @Excel(name = "探索预算", width = 15)
+    @ApiModelProperty(value = "探索预算")
+    private java.math.BigDecimal exploreBudget;
+    /**
+     * 优化目标
+     */
+    @Excel(name = "优化目标", width = 15)
+    @ApiModelProperty(value = "优化目标")
+    private Integer ocpxActionType;
+    /**
+     * 总消耗
+     */
+    @Excel(name = "总消耗", width = 15)
+    @ApiModelProperty(value = "总消耗")
+    private java.math.BigDecimal totalCharge;
+    /**
+     * 封面曝光数
+     */
+    @Excel(name = "封面曝光数", width = 15)
+    @ApiModelProperty(value = "封面曝光数")
+    private Long impression;
+    /**
+     * 封面点击数
+     */
+    @Excel(name = "封面点击数", width = 15)
+    @ApiModelProperty(value = "封面点击数")
+    private Long photoClick;
+    /**
+     * 素材曝光数
+     */
+    @Excel(name = "素材曝光数", width = 15)
+    @ApiModelProperty(value = "素材曝光数")
+    private Long click;
+    /**
+     * 转化数
+     */
+    @Excel(name = "转化数", width = 15)
+    @ApiModelProperty(value = "转化数")
+    private Long unifiedConversion;
+    /**
+     * 转化成本
+     */
+    @Excel(name = "转化成本", width = 15)
+    @ApiModelProperty(value = "转化成本")
+    private java.math.BigDecimal unitfiedConversionCost;
+    /**
+     * 记录日期
+     */
+    @Excel(name = "记录日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "记录日期")
+    private Date statDate;
+    /**
+     * 创建时间
+     */
+    @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+    /**
+     * 修改时间
+     */
+    @Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+    /**
+     * 加速探索状态 0:默认;1:加速探索2:加速探索手动暂停;3:探索金额完成;4:时间到达截止时间,默认开启后只探索 6 小时
+     */
+    private Integer exploreStatus;
+    /**
+     * 可设置的最大加速探索预算,单位:里
+     */
+    private Long maxExploreBudget;
+}

+ 30 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/KuaishouReportDailyExploreMapper.java

@@ -0,0 +1,30 @@
+package cn.com.ctop.kuaishou.modules.report.mapper;
+
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 广告组加速探索报表
+ *
+ * @author jeecg-boot
+ * 2021-08-18
+ * @version V1.0
+ */
+public interface KuaishouReportDailyExploreMapper extends BaseMapper<KuaishouReportDailyExplore> {
+
+    List<KuaishouReportDailyExplore> getUnitListByStudyStatus();
+
+    List<JSONObject> getTodaylist(@Param("accountId") Long accountId, @Param("sortCode") String sortCode, @Param("sortType") String sortType);
+
+    Long getTodaylistTotal(@Param("accountId") Long accountId);
+
+    List<JSONObject> getHistoryList(@Param("request") JSONObject request, @Param("sortCode") String sortCode, @Param("sortType") String sortType);
+
+    Long getHistoryListTotal(@Param("request") JSONObject request);
+
+    List<Long> getUnitIds(@Param("accountId") Long accountId);
+}

+ 103 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaishouReportDailyExploreMapper.xml

@@ -0,0 +1,103 @@
+<?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="cn.com.ctop.kuaishou.modules.report.mapper.KuaishouReportDailyExploreMapper">
+
+    <select id="getUnitListByStudyStatus"
+            resultType="cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore">
+        SELECT account_id, unit_id
+        FROM ctop_kuaishou_report_daily_explore
+        WHERE explore_status IN (0, 1)
+    </select>
+
+    <select id="getTodaylistTotal" resultType="java.lang.Long">
+        SELECT count(1)
+        FROM ctop_kuaishou_group
+        WHERE account_id = #{accountId}
+          AND put_status = 1
+          AND study_status = 1
+          AND unit_id NOT IN (
+            SELECT unit_id FROM ctop_kuaishou_report_daily_explore WHERE account_id = #{accountId}
+        )
+
+    </select>
+
+    <select id="getTodaylist" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+        t2.unit_id,
+        t2.unit_name,
+        IFNULL(charge,'-') as 'charge',
+        IFNULL(activation,'-') as 'activation',
+        IFNULL(ROUND(charge/activation,2),'-') as 'activationCost',
+        IFNULL(event_pay,'-') as 'eventPay',
+        IFNULL(ROUND(charge/event_pay,2),'-') as 'eventPayCost',
+        IFNULL(event_register,'-') as 'eventRegister',
+        IFNULL(ROUND(charge/event_register,2),'-') as 'eventRegisterCost',
+        IFNULL(aclick,'-') as 'aclick'
+        FROM ctop_etl_kuaishou_group_daily_report t1
+        Right JOIN (
+        SELECT unit_id,unit_name FROM ctop_kuaishou_group WHERE account_id = #{accountId} AND unit_id NOT IN (
+        SELECT unit_id FROM ctop_kuaishou_report_daily_explore WHERE account_id = #{accountId}
+        )
+        AND put_status = 1
+        AND study_status = 1
+        ) t2 ON t1.unit_id = t2.unit_id
+        AND stat_date = DATE_FORMAT(now(),'%Y-%m-%d')
+        <if test="sortCode != '' and sortCode != null ">
+            ORDER BY ${sortCode} ${sortType}
+        </if>
+    </select>
+
+    <select id="getHistoryListTotal" resultType="java.lang.Long">
+        SELECT count(1)
+        FROM ctop_kuaishou_report_daily_explore
+        WHERE account_id = #{request.accountId}
+          AND stat_date &gt;= CONCAT(#{request.startTime}, ' 00:00:01')
+          AND stat_date &lt;= CONCAT(#{request.endTime}, ' 23:59:59')
+    </select>
+
+    <select id="getHistoryList" resultType="cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore">
+        SELECT
+        id,
+        account_id,
+        unit_id,
+        unit_name,
+        explore_budget,
+        ocpx_action_type,
+        total_charge,
+        impression,
+        photo_click,
+        click,
+        unified_conversion,
+        unitfied_conversion_cost,
+        stat_date,
+        explore_status
+        FROM ctop_kuaishou_report_daily_explore
+        WHERE account_id = #{request.accountId}
+        AND stat_date &gt;= CONCAT(#{request.startTime},' 00:00:01')
+        AND stat_date &lt;= CONCAT(#{request.endTime},' 23:59:59')
+        <if test="request.unitId != null">
+            AND unit_id = #{request.unitId}
+        </if>
+        <if test="request.unitName != null">
+            AND LOCATE(#{request.unitName},unit_name)
+        </if>
+        <if test="request.exploreStatus != null ">
+            AND explore_status = #{request.exploreStatus}
+        </if>
+        <if test="sortCode != '' and sortCode != null ">
+            ORDER BY ${sortCode} ${sortType}
+        </if>
+    </select>
+
+    <select id="getUnitIds" resultType="java.lang.Long">
+        SELECT unit_id
+        FROM ctop_kuaishou_group
+        WHERE account_id = #{accountId}
+          AND put_status = 1
+          AND study_status = 1
+          AND unit_id NOT IN (
+            SELECT unit_id FROM ctop_kuaishou_report_daily_explore WHERE account_id = #{accountId}
+        )
+    </select>
+
+</mapper>

+ 5 - 5
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/IKuaishouGroupExploreService.java

@@ -11,20 +11,20 @@ import java.math.BigDecimal;
 /**
  * @Description: 广告组的加速探索报表
  * @Author: jeecg-boot
- * @Date:   2021-02-02
+ * @Date: 2021-02-02
  * @Version: V1.0
  */
 public interface IKuaishouGroupExploreService extends IService<KuaishouGroupExplore> {
 
-    Result<Object> unitExploreInfoGet(JSONObject data);
+    Result<Object> unitExploreInfoGet(Long accountId, Long unitId);
 
-    Result<Object> unitExploreBudgetUpdate(JSONObject data);
+    Result<Object> unitExploreBudgetUpdate(Long accountId, Long unitId, Long exploreBudget);
 
     Result<Object> unitExploreStatusPause(JSONObject data);
 
-    Result<Object> querySpeedExploreReport(JSONObject data);
+    Result<Object> querySpeedExploreReport(Long accountId, Long unitId, Integer exploreStatus, Long maxExploreBudget);
 
-    void unitOpenSpeedExplore(Long accountId, Long unitId, BigDecimal groupAccount,Long accountExploreId);
+    void unitOpenSpeedExplore(Long accountId, Long unitId, BigDecimal groupAccount, Long accountExploreId);
 
     void getReportByAccount(CtopOauthToken token);
 

+ 28 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/IKuaishouReportDailyExploreService.java

@@ -0,0 +1,28 @@
+package cn.com.ctop.kuaishou.modules.report.service;
+
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.common.api.vo.Result;
+
+import java.util.List;
+
+/**
+ * 广告组加速探索报表
+ * @author jeecg-boot
+ * 2021-08-18
+ * @version V1.0
+ */
+public interface IKuaishouReportDailyExploreService extends IService<KuaishouReportDailyExplore> {
+
+    void getExploreUnitReports(Long accountId, Long unitId);
+
+    List<KuaishouReportDailyExplore> getUnitListByStudyStatus();
+
+    Result<Object> todaylist(JSONObject request);
+
+    Result<Object> historyList(JSONObject request);
+
+    Result<Object> openBudgets(Long accountId, JSONArray unitIds,Long exploreBudget);
+}

+ 54 - 40
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouGroupExploreServiceImpl.java

@@ -2,6 +2,7 @@ package cn.com.ctop.kuaishou.modules.report.service.impl;
 
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.utils.BigDecimalUtil;
 import cn.com.ctop.common.module.utils.Check;
 import cn.com.ctop.common.module.utils.HttpUtils;
 import cn.com.ctop.common.module.utils.KuaishouInterfaceConstant;
@@ -9,9 +10,13 @@ import cn.com.ctop.common.module.utils.PropertiesUtils;
 import cn.com.ctop.common.module.utils.StatusCode;
 import cn.com.ctop.kuaishou.modules.ai.entity.KuaishouGroupSpeedExploreLog;
 import cn.com.ctop.kuaishou.modules.ai.service.IKuaishouGroupSpeedExploreLogService;
+import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
 import cn.com.ctop.kuaishou.modules.report.entity.KuaishouGroupExplore;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore;
 import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouGroupExploreMapper;
 import cn.com.ctop.kuaishou.modules.report.service.IKuaishouGroupExploreService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyExploreService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -22,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -39,25 +45,23 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
     private ICtopOauthTokenService tokenService;
     @Autowired
     private IKuaishouGroupSpeedExploreLogService groupSpeedExploreLogService;
+    @Autowired
+    private IKuaishouReportDailyExploreService dailyExploreService;
+
+    @Autowired
+    private IKuaiShouGroupService kuaiShouGroupService;
 
     /**
-     * 查询加速探索信息
+     * 查询加速探索状态、预算
      *
      * @param
+     * @return
      * @throws
      * @author ZHAOXA
      */
     @Override
-    public Result<Object> unitExploreInfoGet(JSONObject data) {
+    public Result<Object> unitExploreInfoGet(Long accountId, Long unitId) {
         try {
-            Long accountId = data.getLong("accountId");
-            if (Check.isNull(accountId)) {
-                return Result.error("请选择广告主");
-            }
-            Long unitId = data.getLong("unitId");
-            if (Check.isNull(unitId)) {
-                return Result.error("请选择广告组");
-            }
             CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
             String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.UNIT_EXPLORE_INFO_GET;
             Map<String, String> header = new HashMap<>();
@@ -84,27 +88,16 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
     }
 
     /**
-     * 广告组加速探索预算设置
+     * 开启广告组加速探索
      *
      * @param
      * @throws
      * @author ZHAOXA
      */
     @Override
-    public Result<Object> unitExploreBudgetUpdate(JSONObject data) {
+    public Result<Object> unitExploreBudgetUpdate(Long accountId, Long unitId, Long exploreBudget) {
+        String msg = null;
         try {
-            Long accountId = data.getLong("accountId");
-            if (Check.isNull(accountId)) {
-                return Result.error("请选择广告主");
-            }
-            Long unitId = data.getLong("unitId");
-            if (Check.isNull(unitId)) {
-                return Result.error("请选择广告组");
-            }
-            Long exploreBudget = data.getLong("exploreBudget");
-            if (Check.isNull(exploreBudget)) {
-                return Result.error("请填写加速探索预算");
-            }
             CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
             String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.UNIT_EXPLORE_BUDGET_UPDATE;
             Map<String, String> header = new HashMap<>();
@@ -119,6 +112,21 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
             if (!Check.isNull(resultJson)) {
                 Integer code = resultJson.getInteger("code");
                 if (code == 0) {
+                    Result<Object> result1 = this.unitExploreInfoGet(accountId, unitId);
+                    if (result1.getCode() == 200) {
+                        JSONObject resultData = (JSONObject) result1.getResult();
+                        Integer exploreStatus = resultData.getInteger("explore_status");
+                        Long maxExploreBudget = resultData.getLong("max_explore_budget");
+                        KuaiShouGroup kuaiShouGroup = new KuaiShouGroup();
+
+                        KuaishouReportDailyExplore kuaishouGroupExplore = new KuaishouReportDailyExplore();
+                        kuaishouGroupExplore.setAccountId(accountId);
+                        kuaishouGroupExplore.setUnitId(unitId);
+                        kuaishouGroupExplore.setStatDate(new Date());
+                        kuaishouGroupExplore.setMaxExploreBudget(maxExploreBudget);
+                        kuaishouGroupExplore.setExploreStatus(exploreStatus);
+                        dailyExploreService.save(kuaishouGroupExplore);
+                    }
                     return Result.ok(resultJson.getJSONObject("data"));
                 } else {
                     log.info("广告组的加速探索预算设置失败,accountId:{},返回信息:{}", accountId, resultJson);
@@ -126,7 +134,7 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
                 }
             }
         } catch (Exception e) {
-            log.error("广告组的加速探索预算设置失败", e);
+            log.error("广告组({})启动加速探索失败", unitId, e);
         }
         return Result.error("广告组的加速探索预算设置失败");
     }
@@ -182,16 +190,8 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
      * @author ZHAOXA
      */
     @Override
-    public Result<Object> querySpeedExploreReport(JSONObject data) {
+    public Result<Object> querySpeedExploreReport(Long accountId, Long unitId, Integer exploreStatus, Long maxExploreBudget) {
         try {
-            Long accountId = data.getLong("accountId");
-            if (Check.isNull(accountId)) {
-                return Result.error("请选择广告主");
-            }
-            Long unitId = data.getLong("unitId");
-            if (Check.isNull(unitId)) {
-                return Result.error("请选择广告组");
-            }
             CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
             String url = PropertiesUtils.getConfig("kuaishou_api_url") + KuaishouInterfaceConstant.QUERY_SPEED_EXPLORE_REPORT;
             Map<String, String> header = new HashMap<>();
@@ -206,19 +206,32 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
                 Integer code = resultJson.getInteger("code");
                 if (code == 0) {
                     JSONObject exploreJson = resultJson.getJSONObject("data");
-                    KuaishouGroupExplore kuaishouGroupExplore = JSONObject.toJavaObject(exploreJson, KuaishouGroupExplore.class);
+                    KuaishouReportDailyExplore kuaishouGroupExplore = JSONObject.toJavaObject(exploreJson, KuaishouReportDailyExplore.class);
                     if (Check.isNull(kuaishouGroupExplore)) {
                         return Result.error("查询失败,结果为空");
                     }
-                    QueryWrapper<KuaishouGroupExplore> queryWrapper = new QueryWrapper<>();
-                    queryWrapper.eq("unit_id", kuaishouGroupExplore.getUnitId());
-                    KuaishouGroupExplore one = this.getOne(queryWrapper);
+                    QueryWrapper<KuaishouReportDailyExplore> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("unit_id", unitId);
+                    queryWrapper.eq("account_id", accountId);
+                    KuaishouReportDailyExplore one = dailyExploreService.getOne(queryWrapper);
                     if (!Check.isNull(one)) {
                         kuaishouGroupExplore.setId(one.getId());
                     }
+                    KuaiShouGroup kuaiShouGroup = kuaiShouGroupService.selectGroupByUnitId(accountId, unitId);
+                    if(!Check.isNull(kuaiShouGroup)){
+                        kuaishouGroupExplore.setUnitName(kuaiShouGroup.getUnitName());
+                        kuaishouGroupExplore.setCampaignId(kuaiShouGroup.getCampaignId());
+                    }
                     kuaishouGroupExplore.setAccountId(accountId);
-                    this.saveOrUpdate(kuaishouGroupExplore);
-                    return Result.ok("添加成功");
+                    kuaishouGroupExplore.setExploreStatus(exploreStatus);
+                    kuaishouGroupExplore.setMaxExploreBudget(maxExploreBudget);
+                    kuaishouGroupExplore.setStatDate(new Date());
+                    kuaishouGroupExplore.setExploreBudget(BigDecimalUtil.divideBigDecimal(kuaishouGroupExplore.getExploreBudget(), new BigDecimal(1000)));
+                    kuaishouGroupExplore.setTotalCharge(BigDecimalUtil.divideBigDecimal(kuaishouGroupExplore.getTotalCharge(), new BigDecimal(1000)));
+                    boolean b = dailyExploreService.saveOrUpdate(kuaishouGroupExplore);
+                    if (b) {
+                        return Result.ok("添加成功");
+                    }
                 } else {
                     log.info("查询广告组的加速探索报表失败,accountId:{},返回信息:{}", accountId, resultJson);
                     return Result.error("查询广告组的加速探索报表失败," + resultJson.getString("message"));
@@ -311,4 +324,5 @@ public class KuaishouGroupExploreServiceImpl extends ServiceImpl<KuaishouGroupEx
     }
 
 
+
 }

+ 171 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouReportDailyExploreServiceImpl.java

@@ -0,0 +1,171 @@
+package cn.com.ctop.kuaishou.modules.report.service.impl;
+
+import cn.com.ctop.common.module.utils.Check;
+import cn.com.ctop.kuaishou.modules.app.entity.KuaishouAccountBalanceBudget;
+import cn.com.ctop.kuaishou.modules.app.mapper.KuaishouAccountBalanceBudgetMapper;
+import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
+import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyExplore;
+import cn.com.ctop.kuaishou.modules.report.mapper.KuaishouReportDailyExploreMapper;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouGroupExploreService;
+import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyExploreService;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.util.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 广告组加速探索报表
+ *
+ * @author jeecg-boot
+ * 2021-08-18
+ * @version V1.0
+ */
+@Service
+public class KuaishouReportDailyExploreServiceImpl extends ServiceImpl<KuaishouReportDailyExploreMapper, KuaishouReportDailyExplore> implements IKuaishouReportDailyExploreService {
+
+    @Autowired
+    private KuaishouReportDailyExploreMapper reportDailyExploreMapper;
+
+    @Autowired
+    private KuaishouAccountBalanceBudgetMapper kuaishouAccountBalanceBudgetMapper;
+
+    @Autowired
+    private IKuaishouGroupExploreService kuaishouGroupExploreService;
+
+    @Autowired
+    private IKuaiShouGroupService kuaiShouGroupService;
+
+    @Override
+    public void getExploreUnitReports(Long accountId, Long unitId) {
+        Result<Object> result = kuaishouGroupExploreService.unitExploreInfoGet(accountId, unitId);
+        if (result.getCode() == 200) {
+            JSONObject resultResult = (JSONObject) result.getResult();
+            if (!Check.isNull(resultResult)) {
+                kuaishouGroupExploreService.querySpeedExploreReport(accountId, unitId, resultResult.getInteger("explore_status"),resultResult.getLong("max_explore_budget"));
+            }
+        }
+    }
+
+    @Override
+    public List<KuaishouReportDailyExplore> getUnitListByStudyStatus() {
+        return reportDailyExploreMapper.getUnitListByStudyStatus();
+    }
+
+    @Override
+    public Result<Object> todaylist(JSONObject request) {
+        Integer pageNo = request.getInteger("pageNo");
+        Integer pageSize = request.getInteger("pageSize");
+        if (Check.isNull(pageNo)) {
+            pageNo = 1;
+        }
+        if (Check.isNull(pageSize)) {
+            pageSize = 10;
+        }
+        Long accountId = request.getLong("accountId");
+        if (Check.isNull(accountId)) {
+            return Result.error("未选择账户");
+        }
+        String sortCode = request.getString("sortCode");
+        String sortType = request.getString("sortType");
+        if (Check.isNull(sortCode)) {
+            sortCode = "charge";
+        }
+        if (Check.isNull(sortType)) {
+            sortType = "DESC";
+        }
+        Long total = reportDailyExploreMapper.getTodaylistTotal(accountId);
+        PageHelper.startPage(pageNo, pageSize, false);
+        PageInfo pageInfo = new PageInfo(reportDailyExploreMapper.getTodaylist(accountId, sortCode, sortType));
+        pageInfo.setTotal(total);
+        JSONObject result = new JSONObject();
+        result.put("pageInfo", pageInfo);
+        KuaishouAccountBalanceBudget balanceBudget = kuaishouAccountBalanceBudgetMapper.queryByAccountId(accountId);
+        if (!Check.isNull(balanceBudget)) {
+            result.put("dayBudget", balanceBudget.getDayBudget());
+        }
+        return Result.ok(result);
+    }
+
+    @Override
+    public Result<Object> historyList(JSONObject request) {
+        Integer pageNo = request.getInteger("pageNo");
+        Integer pageSize = request.getInteger("pageSize");
+        if (Check.isNull(pageNo)) {
+            pageNo = 1;
+        }
+        if (Check.isNull(pageSize)) {
+            pageSize = 10;
+        }
+        Long accountId = request.getLong("accountId");
+        if (Check.isNull(accountId)) {
+            return Result.error("未选择账户");
+        }
+        String sortCode = request.getString("sortCode");
+        String sortType = request.getString("sortType");
+        if (Check.isNull(sortCode)) {
+            sortCode = "total_charge";
+        }
+        if (Check.isNull(sortType)) {
+            sortType = "DESC";
+        }
+        if (Check.isNull(request.getString("startTime"))) {
+            request.put("startTime", DateUtils.getNowDate("yyyy-MM-dd"));
+            request.put("endTime", DateUtils.getNowDate("yyyy-MM-dd"));
+        }
+        Long total = reportDailyExploreMapper.getHistoryListTotal(request);
+        PageHelper.startPage(pageNo, pageSize, false);
+        PageInfo pageInfo = new PageInfo(reportDailyExploreMapper.getHistoryList(request, sortCode, sortType));
+        pageInfo.setTotal(total);
+        JSONObject result = new JSONObject();
+        result.put("pageInfo", pageInfo);
+        KuaishouAccountBalanceBudget balanceBudget = kuaishouAccountBalanceBudgetMapper.queryByAccountId(accountId);
+        if (!Check.isNull(balanceBudget)) {
+            result.put("dayBudget", balanceBudget.getDayBudget());
+        }
+        return Result.ok(result);
+    }
+
+    @Override
+    public Result<Object> openBudgets(Long accountId, JSONArray unitIds, Long exploreBudget) {
+        try {
+            StringBuilder errUnitIds = new StringBuilder();
+            if (Check.isNull(unitIds) || unitIds.isEmpty()) {
+                List<Long> unitids = reportDailyExploreMapper.getUnitIds(accountId);
+                for (Long unitid : unitids) {
+                    Result<Object> result = kuaishouGroupExploreService.unitExploreBudgetUpdate(accountId, unitid, exploreBudget);
+                    if (result.getCode() != 200) {
+                        if (errUnitIds.length() > 0) {
+                            errUnitIds.append(",");
+                        }
+                        errUnitIds.append(unitid);
+                    }
+                }
+            } else {
+                for (int i = 0; i < unitIds.size(); i++) {
+                    Long unitId = unitIds.getLong(i);
+                    Result<Object> result = kuaishouGroupExploreService.unitExploreBudgetUpdate(accountId, unitId, exploreBudget);
+                    if (result.getCode() != 200) {
+                        if (errUnitIds.length() > 0) {
+                            errUnitIds.append(",");
+                        }
+                        errUnitIds.append(unitId);
+                    }
+                }
+            }
+            if (errUnitIds.length() > 0) {
+                return Result.ok(errUnitIds.insert(0, "启动完成,其中广告组:").append("启动失败"));
+            }
+            return Result.ok("全部启动完成");
+        } catch (Exception e) {
+            log.error("启动加速探索异常", e);
+            return Result.error("启动加速探索失败");
+        }
+    }
+}