Browse Source

Merge remote-tracking branch 'origin/master_rule_engine' into master_rule_engine

syh 4 years ago
parent
commit
fb24b0da7b
26 changed files with 754 additions and 129 deletions
  1. 6 3
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/constant/MatchLogic.java
  2. 3 3
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleAccountTemplateController.java
  3. 23 9
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleAccountThresholdController.java
  4. 27 3
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleGroupController.java
  5. 79 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleSwitchController.java
  6. 5 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleTemplateController.java
  7. 5 4
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/xml/RuleAccountTemplateMapper.xml
  8. 9 1
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/IRuleAccountThresholdService.java
  9. 3 0
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleAccountTemplateServiceImpl.java
  10. 77 3
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleAccountThresholdServiceImpl.java
  11. 131 88
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleGroupServiceImpl.java
  12. 16 2
      module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleTemplateServiceImpl.java
  13. 13 4
      module-common/src/main/java/cn/com/ctop/common/module/entity/RuleDataAccount.java
  14. 14 0
      module-common/src/main/java/cn/com/ctop/common/module/entity/UserAllocation.java
  15. 2 0
      module-common/src/main/java/cn/com/ctop/common/module/service/IUserAllocationService.java
  16. 13 5
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/RuleDataAccountServiceImpl.java
  17. 10 0
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/UserAllocationServiceImpl.java
  18. 6 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceCheckAccountLandingPageJob.java
  19. 118 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceCheckAccountMonitoringLinkJob.java
  20. 49 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuleDataAccountCleanJob.java
  21. 7 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/IRuleByteDanceAccountService.java
  22. 4 4
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/ReportServiceImpl.java
  23. 45 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/RuleByteDanceAccountServiceImpl.java
  24. 6 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/tool/constants/QueryToolUrlConstant.java
  25. 23 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/tool/service/IByteDanceGetAccountFundService.java
  26. 60 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/tool/service/impl/ByteDanceGetAccountFundServiceImpl.java

+ 6 - 3
module-alarm/src/main/java/cn/com/ctop/alarm/modules/constant/MatchLogic.java

@@ -32,6 +32,9 @@ public class MatchLogic {
     public static boolean matchCondition(String type, String condition, String threshold, String value) {
         try {
             if ("number".equals(type)) {
+                if (Check.isNull(threshold) || Check.isNull(value)) {
+                    return false;
+                }
                 BigDecimal bigThr = new BigDecimal(threshold);
                 BigDecimal bigVal = new BigDecimal(value);
                 switch (condition) {
@@ -87,7 +90,7 @@ public class MatchLogic {
                 }
             }
         } catch (Exception e) {
-            log.error("条件匹配", e);
+            log.error("条件匹配异常", e);
         }
         return false;
     }
@@ -101,7 +104,7 @@ public class MatchLogic {
                 append("预警账户:").append(accountId).append("<br/>");
         if (!Check.isNull(planId) && !Check.isNull(creativeId)) {
             header.append("预警计划:").append(planId).append("<br/>").append("预警创意:").append(creativeId).append("<br/>");
-        } else if (!Check.isNull(creativeId) && Check.isNull(creativeId)) {
+        } else if (!Check.isNull(planId) && Check.isNull(creativeId)) {
             header.append("预警计划:").append(planId).append("<br/>");
         } else if (!Check.isNull(creativeId)) {
             header.append("预警创意:").append(creativeId).append("<br/>");
@@ -129,7 +132,7 @@ public class MatchLogic {
                 ids.add(String.valueOf(id));
             }
         } catch (Exception e) {
-            log.error("ids格式转换异常", e);
+            log.error("数据({})转list异常", strings, e);
         }
         return ids;
     }

+ 3 - 3
module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleAccountTemplateController.java

@@ -70,12 +70,12 @@ public class RuleAccountTemplateController {
     /**
      * 查询账户下关联的模板
      *
-     * @param page
+     * @param pageNo
      * @param pageSize
      * @return
      */
     @GetMapping(value = "/getTemplateApplied")
-    public Result<PageInfo<TemplateAppliedVo>> getTemplateApplied(int page, int pageSize, Long accountId, String projectName, String userName) {
+    public Result<PageInfo<TemplateAppliedVo>> getTemplateApplied(int pageNo, int pageSize, Long accountId, String projectName, String userName) {
         Result<PageInfo<TemplateAppliedVo>> result = new Result<>();
         try {
             LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
@@ -94,7 +94,7 @@ public class RuleAccountTemplateController {
             if (!Check.isNull(userName)) {
                 requestMap.put("userName", userName);
             }
-            PageHelper.startPage(page, pageSize);
+            PageHelper.startPage(pageNo, pageSize);
             List<TemplateAppliedVo> list = ruleAccountTemplateService.getTemplateApplied(requestMap);
 
             PageInfo<TemplateAppliedVo> pageInfo = new PageInfo<>(list);

+ 23 - 9
module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleAccountThresholdController.java

@@ -3,7 +3,9 @@ package cn.com.ctop.alarm.modules.controller;
 import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
 import cn.com.ctop.alarm.modules.service.IRuleAccountThresholdService;
 import cn.com.ctop.common.module.annotation.AutoLog;
+import cn.com.ctop.common.module.utils.Check;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -19,15 +21,7 @@ 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.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
@@ -56,6 +50,26 @@ public class RuleAccountThresholdController {
     @Autowired
     private IRuleAccountThresholdService ruleAccountThresholdService;
 
+
+    @PostMapping(value = "/fillThreshold")
+    public Result<JSONObject> fillThreshold(@RequestBody JSONObject requestJson) {
+        Result<JSONObject> result = new Result<>();
+        try {
+            if (Check.isNull(requestJson)) {
+                throw new Exception("入参为空");
+            }
+            JSONObject returnJson = ruleAccountThresholdService.fillThreshold(requestJson);
+            result.setSuccess(true);
+            result.setResult(returnJson);
+        } catch (Exception e) {
+            e.printStackTrace();
+            result.setSuccess(false);
+            result.setMessage(e.getMessage());
+        }
+        return result;
+    }
+
+
     /**
      * 分页列表查询
      *

+ 27 - 3
module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleGroupController.java

@@ -26,7 +26,15 @@ 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.*;
+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;
@@ -36,7 +44,11 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  * 规则组
@@ -74,7 +86,6 @@ public class RuleGroupController {
             if (Check.isNull(requestJson)) {
                 throw new Exception("请输出需要创建的参数");
             }
-
             JSONObject returnJson = ruleGroupService.createRuleGroup(requestJson);
             if (returnJson.getInteger("code") == 0) {
                 result.setSuccess(true);
@@ -186,6 +197,19 @@ public class RuleGroupController {
         return result;
     }
 
+    @GetMapping(value = "/checkRules")
+    public Result<RuleGroup> checkRules() {
+        Result<RuleGroup> result = new Result<>();
+        try {
+            ruleGroupService.checkRules();
+            result.success("成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
     /**
      * 编辑
      *

+ 79 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleSwitchController.java

@@ -0,0 +1,79 @@
+package cn.com.ctop.alarm.modules.controller;
+
+import cn.com.ctop.common.module.entity.UserAllocation;
+import cn.com.ctop.common.module.service.IUserAllocationService;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import org.jeecg.common.api.vo.Result;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/rule/switch/")
+public class RuleSwitchController {
+
+    @Autowired
+    IUserAllocationService userAllocationService;
+
+    /**
+     *  账户添加内广监测链接预警
+     */
+    @PostMapping(value = "/onOrOffMonitoringLink")
+    public Result<Object> onOrOffMonitoringLink(@RequestParam Long accountId, @RequestParam String switchType){
+        Result<Object> result=new Result<>();
+        UserAllocation userAllocation=new UserAllocation();
+        userAllocation.setAccountId(accountId);
+        UpdateWrapper<UserAllocation> wrapper=new UpdateWrapper<>();
+        //开启预警
+        if(switchType.equals("on")){
+            wrapper.set("landing_page",0);
+            wrapper.setEntity(userAllocation);
+            boolean update = userAllocationService.update(wrapper);
+            if(update){
+                result.success("监测链接预警开启成功");
+            }
+        }else if(switchType.equals("off")){
+            wrapper.set("landing_page",1);
+            wrapper.setEntity(userAllocation);
+            boolean update = userAllocationService.update(wrapper);
+            if(update){
+                result.success("监测链接预警关闭成功");
+            }
+        }else {
+            result.error500("未知操作");
+        }
+        return result;
+    }
+
+    /**
+     *  账户添加落地页链接预警
+     */
+    @PostMapping(value = "/onOrOffLandingPage")
+    public Result<Object> onOrOffLandingPage(@RequestParam Long accountId, @RequestParam String switchType){
+        Result<Object> result=new Result<>();
+        UserAllocation userAllocation=new UserAllocation();
+        userAllocation.setAccountId(accountId);
+        UpdateWrapper<UserAllocation> wrapper=new UpdateWrapper<>();
+        //开启预警
+        if(switchType.equals("on")){
+            wrapper.set("landing_page",0);
+            wrapper.setEntity(userAllocation);
+            boolean update = userAllocationService.update(wrapper);
+            if(update){
+                result.success("落地页链接预警开启成功");
+            }
+        }else if(switchType.equals("off")){
+            wrapper.set("landing_page",1);
+            wrapper.setEntity(userAllocation);
+            boolean update = userAllocationService.update(wrapper);
+            if(update){
+                result.success("落地页链接预警关闭成功");
+            }
+        }else {
+            result.error500("未知操作");
+        }
+        return result;
+    }
+}

+ 5 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/controller/RuleTemplateController.java

@@ -128,7 +128,12 @@ public class RuleTemplateController {
                                                      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                      HttpServletRequest req) {
         Result<IPage<RuleTemplate>> result = new Result<>();
+        String templateName = ruleTemplate.getTemplateName();
+        ruleTemplate.setTemplateName(null);
         QueryWrapper<RuleTemplate> queryWrapper = QueryGenerator.initQueryWrapper(ruleTemplate, req.getParameterMap());
+        if (!Check.isNull(templateName)) {
+            queryWrapper.like("template_name", templateName);
+        }
         Page<RuleTemplate> page = new Page<RuleTemplate>(pageNo, pageSize);
         IPage<RuleTemplate> pageList = ruleTemplateService.page(page, queryWrapper);
         result.setSuccess(true);

+ 5 - 4
module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/xml/RuleAccountTemplateMapper.xml

@@ -4,8 +4,9 @@
 
     <select id="getTemplateApplied" parameterType="Map"
             resultType="cn.com.ctop.alarm.modules.entity.vo.TemplateAppliedVo">
-        t1.account_id accountId,SELECT
-        t2.auth_name autnName,
+        select
+        t1.account_id accountId,
+        t2.auth_name authName,
         t1.template_id templateId,
         (
         SELECT
@@ -14,7 +15,7 @@
         ctop_rule_template
         WHERE
         id = t1.template_id
-        ) templateName,
+        ) as templateName,
         t3.id projectId,
         t3.project_name projectName,
         t2.user_id userId,
@@ -23,7 +24,7 @@
         ctop_rule_account_template t1
         LEFT JOIN ctop_user_allocation t2 ON t1.account_id = t2.account_id
         LEFT JOIN ctop_project t3 ON t2.project_id = t3.id
-        left sys_user t4 on t2.user_id = t4.id
+        left join sys_user t4 on t2.user_id = t4.id
         where 1 = 1
         <if test="params.userId !=null and params.userId !='' ">
             and t2.user_id = #{params.userId}

+ 9 - 1
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/IRuleAccountThresholdService.java

@@ -1,14 +1,22 @@
 package cn.com.ctop.alarm.modules.service;
 
 import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
 
 /**
  * @Description: 规则关联账户 阈值
  * @Author: jeecg-boot
- * @Date:   2020-11-15
+ * @Date: 2020-11-15
  * @Version: V1.0
  */
 public interface IRuleAccountThresholdService extends IService<RuleAccountThreshold> {
 
+    /**
+     * 阈值填充
+     *
+     * @param requestJson
+     * @return
+     */
+    JSONObject fillThreshold(JSONObject requestJson) throws Exception;
 }

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

@@ -87,6 +87,9 @@ public class RuleAccountTemplateServiceImpl extends ServiceImpl<RuleAccountTempl
                 RuleAccountThreshold threshold = new RuleAccountThreshold();
                 threshold.setAccountId(accountId);
                 threshold.setRuleId(ruleBase.getId());
+                if (ruleBase.getVariableType() == 0) {
+                    threshold.setThreshoId(ruleBase.getThreshold());
+                }
                 ruleAccountThresholdService.save(threshold);
             }
 

+ 77 - 3
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleAccountThresholdServiceImpl.java

@@ -3,17 +3,91 @@ package cn.com.ctop.alarm.modules.service.impl;
 import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
 import cn.com.ctop.alarm.modules.mapper.RuleAccountThresholdMapper;
 import cn.com.ctop.alarm.modules.service.IRuleAccountThresholdService;
-import org.springframework.stereotype.Service;
-
+import cn.com.ctop.common.module.utils.Check;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
 /**
  * 规则关联账户 阈值
+ *
  * @author jeecg-boot
- * @date   2020-11-15
  * @version V1.0
+ * @date 2020-11-15
  */
 @Service
 public class RuleAccountThresholdServiceImpl extends ServiceImpl<RuleAccountThresholdMapper, RuleAccountThreshold> implements IRuleAccountThresholdService {
+    @Autowired
+    private RuleAccountThresholdMapper ruleAccountThresholdMapper;
+
+    /**
+     * 填充阈值
+     *
+     * @param requestJson
+     * @return
+     */
+    @Override
+    public JSONObject fillThreshold(JSONObject requestJson) throws Exception {
+        Long accountId = requestJson.getLong("accountId");
+        if (Check.isNull(accountId)) {
+            throw new Exception("请传入账户id");
+        }
+        JSONArray ruleList = requestJson.getJSONArray("ruleList");
+        if (Check.isNull(ruleList)) {
+            throw new Exception("请输入具体的规则字段");
+        }
+        Integer updateCount = 0;
+        for (int i = 0; i < ruleList.size(); i++) {
+            JSONObject groupJson = ruleList.getJSONObject(i);
+            if (Check.isNull(groupJson)) {
+                continue;
+            }
+            JSONArray ruleDetail = groupJson.getJSONArray("ruleDetail");
+            if (Check.isNull(ruleDetail)) {
+                continue;
+            }
+
+            for (int j = 0; j < ruleDetail.size(); j++) {
+                JSONObject ruleJson = ruleDetail.getJSONObject(j);
+                Long ruleId = ruleJson.getLong("ruleId");
+                if (Check.isNull(ruleId)) {
+                    continue;
+                }
+                String threshold = ruleJson.getString("threshold");
+                if (Check.isNull(threshold)) {
+                    continue;
+                }
+                RuleAccountThreshold updateThreshold = new RuleAccountThreshold();
+                /*if (threshold.contains("[") && threshold.contains("]")) {
+                  *//*  String replace = threshold.replace("[", "").replace("]", "");
+                    List<String> strings = Arrays.asList(replace.split(","));
+                    JSONArray array = new JSONArray();
+                    for (int k = 0; k < strings.size(); k++) {
+                        array.add(strings.get(i))
+                         JSONArray.parseArray(strings);
+                    }*//*
+
+                    updateThreshold.setThreshoId(JSONArray.parseArray(threshold).toJSONString());
+                } else {
+
+                }*/
+                updateThreshold.setThreshoId(threshold);
+                QueryWrapper<RuleAccountThreshold> updateQueryWrapper = new QueryWrapper();
+                updateQueryWrapper.eq("account_id", accountId);
+                updateQueryWrapper.eq("rule_id", ruleId);
+                int update = ruleAccountThresholdMapper.update(updateThreshold, updateQueryWrapper);
+                if (update > 0) {
+                    updateCount += 1;
+                }
+            }
+        }
 
+        JSONObject returnJson = new JSONObject();
+        returnJson.put("code", 0);
+        returnJson.put("updateCount", updateCount);
+        return returnJson;
+    }
 }

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

@@ -1,8 +1,18 @@
 package cn.com.ctop.alarm.modules.service.impl;
 
 import cn.com.ctop.alarm.modules.constant.MatchLogic;
-import cn.com.ctop.alarm.modules.entity.*;
-import cn.com.ctop.alarm.modules.mapper.*;
+import cn.com.ctop.alarm.modules.entity.RuleAccountTemplate;
+import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
+import cn.com.ctop.alarm.modules.entity.RuleBase;
+import cn.com.ctop.alarm.modules.entity.RuleGroup;
+import cn.com.ctop.alarm.modules.entity.RuleIndicator;
+import cn.com.ctop.alarm.modules.entity.RuleTemplate;
+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.IRuleAccountTemplateService;
 import cn.com.ctop.alarm.modules.service.IRuleGroupService;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
@@ -109,82 +119,86 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
             return;
         }
         log.info("已获取账户({})的数据,开始匹配规则", accountId);
-        for (RuleGroup ruleGroup : ruleGroups) {
-            List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
-            if (Check.isNull(ruleBaseList)) {
-                continue;
-            }
-            boolean isBase = "base".equals(ruleGroup.getRuleType());
-            //匹配单规则
-            if (isBase) {
-                RuleBase ruleBase = ruleBaseList.get(0);
-                //指标对象
-                JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
-                //指标阈值
-                String threshold = thresholdObj.getString(ruleBase.getId().toString());
-                //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
-                if (Check.isNull(threshold) || "unlimited".equals(threshold)) {
-                    log.warn("阈值为空/不限,该规则({})不执行", ruleBase.getId());
+        try {
+            for (RuleGroup ruleGroup : ruleGroups) {
+                List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
+                if (Check.isNull(ruleBaseList)) {
                     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.getString("dataType"), ruleBase.getRuleCondition(), threshold, value)) {
-                            sendMsg(ruleGroup, obj);
-                        }
-                    }
-                }
-                //匹配组合规则
-            } else {
-                boolean flag = false;
-                //符合规则的数据集
-                JSONArray targetDatas = new JSONArray();
-                JSONArray planDatas = new JSONArray();
-                JSONArray creativeDatas = new JSONArray();
-                JSONArray accountDatas = new JSONArray();
-                for (RuleBase ruleBase : ruleBaseList) {
+                boolean isBase = "base".equals(ruleGroup.getRuleType());
+                //匹配单规则
+                if (isBase) {
+                    RuleBase ruleBase = ruleBaseList.get(0);
                     //指标对象
                     JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
-                    //阈值类型
-                    String dataType = indicator.getString("dataType");
                     //指标阈值
                     String threshold = thresholdObj.getString(ruleBase.getId().toString());
                     //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
                     if (Check.isNull(threshold) || "unlimited".equals(threshold)) {
+                        log.warn("阈值为空/不限,该规则({})不执行", ruleBase.getId());
                         continue;
                     }
+                    //维度数据
                     JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
-                    //账户维度数据
-                    if ("account".equals(ruleBase.getRuleDimension())) {
-                        JSONObject accountEntity = dimensionData.getJSONObject(0);
-                        if (MatchLogic.matchCondition(dataType, ruleBase.getRuleCondition(), threshold, accountEntity.getString(ruleBase.getIndicatorCode()))) {
-                            accountDatas.add(accountEntity);
-                        } else {
-                            log.warn("判断规则组({}),账户规则不符合", ruleGroup.getId());
-                            break;
+                    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.getString("dataType"), ruleBase.getRuleCondition(), threshold, value)) {
+                                sendMsg(ruleGroup, obj);
+                            }
                         }
-                    } else if ("plan".equals(ruleBase.getRuleDimension())) {
-                        planDatas = getOKData(planDatas, dimensionData, ruleBase, dataType, threshold);
-                    } else if ("creative".equals(ruleBase.getRuleDimension())) {
-                        creativeDatas = getOKData(creativeDatas, dimensionData, ruleBase, dataType, threshold);
-                    } else if ("target".equals(ruleBase.getRuleDimension())) {
-                        targetDatas = getOKData(targetDatas, dimensionData, ruleBase, dataType, threshold);
                     }
+                    //匹配组合规则
+                } else {
+                    boolean flag = false;
+                    //符合规则的数据集
+                    JSONArray targetDatas = new JSONArray();
+                    JSONArray planDatas = new JSONArray();
+                    JSONArray creativeDatas = new JSONArray();
+                    JSONArray accountDatas = new JSONArray();
+                    for (RuleBase ruleBase : ruleBaseList) {
+                        //指标对象
+                        JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
+                        //阈值类型
+                        String dataType = indicator.getString("dataType");
+                        //指标阈值
+                        String threshold = thresholdObj.getString(ruleBase.getId().toString());
+                        //阈值为空时,或者阈值为“unlimited”(不限),不执行该规则
+                        if (Check.isNull(threshold) || "unlimited".equals(threshold)) {
+                            continue;
+                        }
+                        JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
+                        //账户维度数据
+                        if ("account".equals(ruleBase.getRuleDimension())) {
+                            JSONObject accountEntity = dimensionData.getJSONObject(0);
+                            if (MatchLogic.matchCondition(dataType, ruleBase.getRuleCondition(), threshold, accountEntity.getString(ruleBase.getIndicatorCode()))) {
+                                accountDatas.add(accountEntity);
+                            } else {
+                                log.warn("判断规则组({}),账户规则不符合", ruleGroup.getId());
+                                break;
+                            }
+                        } else if ("plan".equals(ruleBase.getRuleDimension())) {
+                            planDatas = getOKData(planDatas, dimensionData, ruleBase, dataType, threshold);
+                        } else if ("creative".equals(ruleBase.getRuleDimension())) {
+                            creativeDatas = getOKData(creativeDatas, dimensionData, ruleBase, dataType, threshold);
+                        } else if ("target".equals(ruleBase.getRuleDimension())) {
+                            targetDatas = getOKData(targetDatas, dimensionData, ruleBase, dataType, threshold);
+                        }
 
-                }
-                //获取达标可发送的数据
-                JSONArray sendData = MatchLogic.getSendData(accountDatas, planDatas, creativeDatas, targetDatas);
-                if (!Check.isNull(sendData)) {
-                    //执行发送
-                    for (int i = 0; i < sendData.size(); i++) {
-                        sendMsg(ruleGroup, sendData.getJSONObject(i));
+                    }
+                    //获取达标可发送的数据
+                    JSONArray sendData = MatchLogic.getSendData(accountDatas, planDatas, creativeDatas, targetDatas);
+                    if (!Check.isNull(sendData)) {
+                        //执行发送
+                        for (int i = 0; i < sendData.size(); i++) {
+                            sendMsg(ruleGroup, sendData.getJSONObject(i));
+                        }
                     }
                 }
             }
+        } catch (Exception e) {
+            log.error("匹配规则逻辑异常", e);
         }
     }
 
@@ -233,12 +247,14 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         Long planId = obj.getLong("planId");
         Long accountId = obj.getLong("accountId");
         JSONObject user = getUserByAccountId(accountId);
-        boolean isPause = "PAUSE".equals(ruleGroup.getOperate());
+        //TODO 关停操作
+        boolean isPause = false;
+          /*      "PAUSE".equals(ruleGroup.getOperate());
         if (isPause) {
             if (shutDown(accountId, planId, creativeId, user.getString("id"))) {
                 isPause = true;
             }
-        }
+        }*/
         String msg = MatchLogic.getMsg(ruleGroup, user, accountId, planId, creativeId, isPause);
         String sendType = ruleGroup.getSendType();
         if ("SMS".equals(sendType)) {
@@ -252,11 +268,19 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         }
     }
 
+    /**
+     * 根据accountId获取人员对象
+     *
+     * @param
+     * @return com.alibaba.fastjson.JSONObject
+     * @throws
+     * @author ZHAOXA
+     */
     private JSONObject getUserByAccountId(Long accountId) {
         JSONObject obj = userObj.getJSONObject(accountId.toString());
         if (Check.isNull(obj)) {
             JSONObject user = sysUserMapper.selectUserByAccount(accountId);
-            obj.put(accountId.toString(), user);
+            userObj.put(accountId.toString(), user);
             return user;
         }
         return obj;
@@ -290,22 +314,31 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
         if (Check.isNull(thresholdList)) {
             return null;
         }
-        JSONObject obj = new JSONObject();
-        for (RuleAccountThreshold threshold : thresholdList) {
-            obj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshoId());
+        JSONObject obj = null;
+        try {
+            obj = new JSONObject();
+            for (RuleAccountThreshold threshold : thresholdList) {
+                obj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshoId());
+            }
+        } catch (Exception e) {
+            log.error("获取账户阈值数据集失败", e);
         }
         return obj;
     }
 
     //整理指标数据
     public JSONObject getRuleIndicator() {
-        List<RuleIndicator> indicators = ruleIndicatorMapper.selectByMap(null);
-        if (Check.isNull(indicators)) {
-            return null;
-        }
         JSONObject obj = new JSONObject();
-        for (RuleIndicator indicator : indicators) {
-            obj.put(indicator.getCode(), indicators);
+        try {
+            List<RuleIndicator> indicators = ruleIndicatorMapper.selectByMap(null);
+            if (Check.isNull(indicators)) {
+                return null;
+            }
+            for (RuleIndicator indicator : indicators) {
+                obj.put(indicator.getCode(), indicator);
+            }
+        } catch (Exception e) {
+            log.error("获取指标数据集异常", e);
         }
         return obj;
     }
@@ -320,20 +353,25 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @author ZHAOXA
      */
     private Map<Long, List<RuleGroup>> getRuleGroupMap() {
-        Map<Long, List<RuleGroup>> map = new HashMap<>();
-        List<RuleTemplate> ruleTemplates = ruleTemplateMapper.selectByMap(null);
-        ruleTemplates.forEach(tem -> {
-            QueryWrapper<RuleGroup> groupWrapper = new QueryWrapper<>();
-            groupWrapper.eq("template_id", tem.getId());
-            List<RuleGroup> ruleGroups = ruleGroupMapper.selectList(groupWrapper);
-            for (RuleGroup group : ruleGroups) {
-                QueryWrapper<RuleBase> baseWrapper = new QueryWrapper<>();
-                baseWrapper.eq("group_id", group.getId());
-                baseWrapper.orderByDesc("is_unlimited");
-                group.setRuleBaseList(ruleBaseMapper.selectList(baseWrapper));
-            }
-            map.put(tem.getId(), ruleGroups);
-        });
+        try {
+            Map<Long, List<RuleGroup>> map = new HashMap<>();
+            List<RuleTemplate> ruleTemplates = ruleTemplateMapper.selectByMap(null);
+            ruleTemplates.forEach(tem -> {
+                QueryWrapper<RuleGroup> groupWrapper = new QueryWrapper<>();
+                groupWrapper.eq("template_id", tem.getId());
+                List<RuleGroup> ruleGroups = ruleGroupMapper.selectList(groupWrapper);
+                for (RuleGroup group : ruleGroups) {
+                    QueryWrapper<RuleBase> baseWrapper = new QueryWrapper<>();
+                    baseWrapper.eq("group_id", group.getId());
+                    baseWrapper.orderByDesc("is_unlimited");
+                    group.setRuleBaseList(ruleBaseMapper.selectList(baseWrapper));
+                }
+                map.put(tem.getId(), ruleGroups);
+            });
+            return map;
+        } catch (Exception e) {
+            log.error("获取模板规则组集合异常", e);
+        }
         return null;
     }
 
@@ -347,7 +385,12 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @author ZHAOXA
      */
     private JSONObject getRuleData(Long accountId) {
-        return ruleDataAccountService.getRuleDataByAccountId(accountId);
+        try {
+            return ruleDataAccountService.getRuleDataByAccountId(accountId);
+        } catch (Exception e) {
+            log.error("获取匹配数据集异常", e);
+        }
+        return null;
     }
 
     /**

+ 16 - 2
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/impl/RuleTemplateServiceImpl.java

@@ -255,7 +255,7 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
     public JSONObject queryDetailByAccountIdAndTemplateId(Long accountId, Long templateId) throws Exception {
         JSONObject returnJson = new JSONObject();
         RuleTemplate template = ruleTemplateMapper.selectById(templateId);
-        if (Check.isNull(ruleTemplateMapper)) {
+        if (Check.isNull(template)) {
             throw new Exception("获取模板基本信息为空");
         }
 
@@ -307,8 +307,21 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
                 accountThresholdQueryWrapper.eq("rule_id", ruleId);
                 RuleAccountThreshold threshold = accountThresholdService.getOne(accountThresholdQueryWrapper);
                 if (!Check.isNull(threshold)) {
-                    ruleJson.put("threshold", threshold.getThreshoId());
+                    String value = threshold.getThreshoId();
+                    if (!Check.isNull(value)) {
+                        if (value.contains("[") && value.contains("]")) {
+                            ruleJson.put("threshold", JSONArray.parseArray(value));
+                        } else {
+                            ruleJson.put("threshold", value);
+                        }
+                    }else{
+                        ruleJson.put("threshold", null);
+                    }
+                   // ruleJson.put("threshold", threshold.getThreshoId());
+                } else {
+                    ruleJson.put("threshold", null);
                 }
+
                 ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
                 ruleJson.put("variableType", ruleBase.getVariableType());
                 ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
@@ -337,4 +350,5 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
         returnJson.put("ruleList", ruleList);
         return returnJson;
     }
+
 }

+ 13 - 4
module-common/src/main/java/cn/com/ctop/common/module/entity/RuleDataAccount.java

@@ -3,6 +3,7 @@ package cn.com.ctop.common.module.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -22,11 +23,19 @@ import java.util.Date;
 @TableName("ctop_rule_data_account")
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
+@ApiModel(value="ctop_rule_data_account对象", description="规则账户清洗数据")
 public class RuleDataAccount {
 
-	@TableId(type = IdType.AUTO)
+	/**id*/
+    @ApiModelProperty(value = "id")
 	private Long id;
+	/**账户id*/
+	@Excel(name = "账户id", width = 15)
+    @ApiModelProperty(value = "账户id")
 	private Long accountId;
+	/**账户name*/
+	@Excel(name = "账户id", width = 15)
+	@ApiModelProperty(value = "账户id")
 	private String accountName;
 	/**消耗*/
 	@Excel(name = "消耗", width = 15)
@@ -52,6 +61,9 @@ public class RuleDataAccount {
 	@Excel(name = "nextDayOpenCost", width = 15)
     @ApiModelProperty(value = "nextDayOpenCost")
 	private BigDecimal nextDayOpenCost;
+
+	private BigDecimal nextDayOpenRate;
+
 	/**status*/
 	@Excel(name = "status", width = 15)
     @ApiModelProperty(value = "status")
@@ -62,7 +74,4 @@ public class RuleDataAccount {
 	/**updateTime*/
     @ApiModelProperty(value = "updateTime")
 	private Date updateTime;
-
-	public RuleDataAccount() {
-	}
 }

+ 14 - 0
module-common/src/main/java/cn/com/ctop/common/module/entity/UserAllocation.java

@@ -112,6 +112,20 @@ public class UserAllocation implements Serializable {
     private Integer accountStatus;
 
     /**
+     * 检测链接预警
+     * 0 启动
+     * 1 禁用
+     */
+    private Integer monitoringLink;
+
+    /**
+     * 检测链接预警
+     * 0 启动
+     * 1 禁用
+     */
+    private Integer landingPage;
+
+    /**
      * 修改时间
      */
     @Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")

+ 2 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/IUserAllocationService.java

@@ -32,4 +32,6 @@ public interface IUserAllocationService extends IService<UserAllocation> {
     List<JSONObject> getUserIdListByProjectId(Long projectId);
 
     List<JSONObject> getAccountIdListByUserId(Long userId);
+
+    List<UserAllocation> getUserAllocations(String mediaId ,int switchType);
 }

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

@@ -1,6 +1,9 @@
 package cn.com.ctop.common.module.service.impl;
 
 import cn.com.ctop.common.module.entity.RuleDataAccount;
+import cn.com.ctop.common.module.entity.RuleDataCreative;
+import cn.com.ctop.common.module.entity.RuleDataPlan;
+import cn.com.ctop.common.module.entity.RuleDataTarget;
 import cn.com.ctop.common.module.mapper.RuleDataAccountMapper;
 import cn.com.ctop.common.module.mapper.RuleDataCreativeMapper;
 import cn.com.ctop.common.module.mapper.RuleDataPlanMapper;
@@ -13,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -42,11 +46,15 @@ public class RuleDataAccountServiceImpl extends ServiceImpl<RuleDataAccountMappe
         JSONObject obj = new JSONObject();
         Map<String, Object> map = new HashMap<>();
         map.put("account_id", accountId);
-        map.put("status", NoEn.NO1.valueStr());
-        obj.put("account", ruleDataAccountMapper.selectByMap(map));
-        obj.put("plan", ruleDataPlanMapper.selectByMap(map));
-        obj.put("target", ruleDataTargetMapper.selectByMap(map));
-        obj.put("creative", ruleDataCreativeMapper.selectByMap(map));
+        map.put("status", NoEn.NO1.valueInt());
+        List<RuleDataAccount> ruleDataAccounts = ruleDataAccountMapper.selectByMap(map);
+        obj.put("account", ruleDataAccounts);
+        List<RuleDataPlan> ruleDataPlans = ruleDataPlanMapper.selectByMap(map);
+        obj.put("plan", ruleDataPlans);
+        List<RuleDataTarget> ruleDataTargets = ruleDataTargetMapper.selectByMap(map);
+        obj.put("target", ruleDataTargets);
+        List<RuleDataCreative> ruleDataCreatives = ruleDataCreativeMapper.selectByMap(map);
+        obj.put("creative", ruleDataCreatives);
         return obj;
     }
 }

+ 10 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/impl/UserAllocationServiceImpl.java

@@ -119,4 +119,14 @@ public class UserAllocationServiceImpl extends ServiceImpl<UserAllocationMapper,
     public List<JSONObject> getAccountIdListByUserId(Long userId) {
         return userAllocationMapper.getAccountIdListByUserId(userId);
     }
+
+    @Override
+    public List<UserAllocation> getUserAllocations(String mediaId, int switchType) {
+        QueryWrapper<UserAllocation> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("media_id", mediaId);
+        queryWrapper.eq("account_status", 0);
+        queryWrapper.eq("monitoring_link", 0);
+        queryWrapper.orderByDesc("create_time");
+        return this.list(queryWrapper);
+    }
 }

+ 6 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceCheckAccountLandingPageJob.java

@@ -0,0 +1,6 @@
+package cn.com.ctop.job.bytedance.handler;
+
+public class ByteDanceCheckAccountLandingPageJob {
+
+
+}

+ 118 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDanceCheckAccountMonitoringLinkJob.java

@@ -0,0 +1,118 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.common.module.entity.UserAllocation;
+import cn.com.ctop.common.module.service.ISendMessageService;
+import cn.com.ctop.common.module.service.IUserAllocationService;
+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.JSONObject;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.log.XxlJobLogger;
+import org.jeecg.common.util.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+public class ByteDanceCheckAccountMonitoringLinkJob {
+
+    @Autowired
+    private IUserAllocationService allocationService;
+    @Autowired
+    private IByteDanceAdvertisePlanService advertisePlanService;
+    @Autowired
+    private IByteDanceCreativeService creativeService;
+    @Autowired
+    private ISendMessageService sendMessageService;
+
+    @XxlJob("byteDanceCheckAccountMonitoringLinkJob")
+    public ReturnT<String> execute(String param) throws Exception{
+
+        //查询开启监测链接预警的账户
+        //Todo 暂时单线程
+        List<UserAllocation> userAllocations=allocationService.getUserAllocations("1",0);
+        userAllocations.forEach(userAllocation->{
+            List<ByteDanceAdvertisePlan> plans = advertisePlanService.getAllPlans(userAllocation.getAccountId(), DateUtils.formatDate(new Date()));
+            if(null!=plans&&!plans.isEmpty()){
+                for (ByteDanceAdvertisePlan plan:plans) {
+                    Map<String, Object> creativeDetail = creativeService.getCreativeDetail(userAllocation.getAccountId(), plan.getId());
+                    if(null!=creativeDetail.get("data")){
+                        JSONObject data = (JSONObject) creativeDetail.get("data");
+                        checkMonitorLink(data,plan,userAllocation);
+                    }
+                }
+            }
+        });
+        XxlJobLogger.log("监测链接检查完成");
+        return ReturnT.SUCCESS;
+    }
+
+    private void checkMonitorLink(JSONObject data, ByteDanceAdvertisePlan plan, UserAllocation allocation) {
+        String downloadUrl = plan.getDownloadUrl();
+        boolean errorflag = false;
+        String errorMsg = "";
+        String token = plan.getName().split("-")[0];
+        if(null!=token&& "衍生计划".equals(token)){
+            token = plan.getName().split("-")[1];
+        }
+        String tokenInfo = "surl_token="+token;
+        String appType = plan.getAppType();
+
+        if(null!=downloadUrl){
+            if(null!=appType&& "APP_IOS".equals(appType)){
+//                if(!downloadUrl.equals("https://apps.apple.com/cn/app/id1468454200")){
+                if(!downloadUrl.contains("https://apps.apple.com/cn/app")){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&& "APP_ANDROID".equals(appType)){
+                if(!downloadUrl.contains(token)){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //展示监测链接
+        String trackUrl = data.getString("trackUrl");
+        if(null!=trackUrl&&!"".equals(trackUrl.trim())){
+            if(!trackUrl.contains(tokenInfo)){
+                errorMsg+= "展示监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        //点击监测链接
+        String actionTrackUrl = data.getString("actionTrackUrl");
+        if(null!=actionTrackUrl&&!"".equals(actionTrackUrl.trim())){
+            if(null!=appType&& "APP_IOS".equals(appType)){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("app_platform=ios")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&& "APP_ANDROID".equals(appType)){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("tt/")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //视频有效播放监测链接
+        String videoPlayEffectiveTrackUrl = data.getString("videoPlayEffectiveTrackUrl");
+        if(null!=videoPlayEffectiveTrackUrl&&!"".equals(videoPlayEffectiveTrackUrl.trim())){
+            if(!videoPlayEffectiveTrackUrl.contains(tokenInfo)){
+                errorMsg+= "视频有效播放监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        if(errorflag){
+            sendMessage(allocation,"警告:账户:"+allocation.getAuthName()+"(id:"+allocation.getAccountId()+")下的广告计划:"+plan.getName()+"(id:"+plan.getId()+")"+"监测链接异常>>"+errorMsg);
+        }
+    }
+    private void sendMessage(UserAllocation allocation, String errorMsg) {
+        sendMessageService.sendMessage(allocation.getUserId(),errorMsg);
+    }
+}

+ 49 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuleDataAccountCleanJob.java

@@ -0,0 +1,49 @@
+package cn.com.ctop.job.bytedance.handler;
+
+/**
+ *  Created by JQ.bi on 2020.11.16
+ */
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.toutiao.modules.report.service.IRuleByteDanceAccountService;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.log.XxlJobLogger;
+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
+public class RuleDataAccountCleanJob {
+
+    @Autowired
+    private ICtopOauthTokenService oauthTokenService;
+
+    @Autowired
+    private IRuleByteDanceAccountService ruleByteDanceAccountService;
+
+    private ExecutorService executorPool = Executors.newFixedThreadPool(6);
+
+    @XxlJob("ruleDataAccountCleanJob")
+    public ReturnT<String> execute(String param) throws Exception {
+        XxlJobLogger.log("规则预警账户维度数据开始清洗");
+        //查询所有头条账户
+        List<CtopOauthToken> tokens = oauthTokenService.selectToutiaoToken();
+        if (null == tokens || tokens.isEmpty()) {
+            XxlJobLogger.log("未获取到可用的token");
+            return ReturnT.FAIL;
+        }
+        tokens.forEach(token->executorPool.submit(() -> {
+            ruleByteDanceAccountService.cleanRuleDataAccount(token.getAccountId());
+        }));
+        if(!executorPool.isShutdown()){
+            executorPool.shutdown();
+        }
+        XxlJobLogger.log("规则预警账户维度数据清洗结束");
+        return ReturnT.SUCCESS;
+    }
+}

+ 7 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/IRuleByteDanceAccountService.java

@@ -0,0 +1,7 @@
+package cn.com.ctop.toutiao.modules.report.service;
+
+public interface IRuleByteDanceAccountService {
+
+    void cleanRuleDataAccount(Long accountId);
+
+}

+ 4 - 4
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/ReportServiceImpl.java

@@ -99,13 +99,13 @@ public class ReportServiceImpl implements IReportService {
             return;
         }
 
-        for (var i = 0; i < dataArray.size(); i++) {
-            var data = dataArray.getJSONObject(i);
+        for (int i = 0; i < dataArray.size(); i++) {
+            JSONObject data = dataArray.getJSONObject(i);
             if (null != conditions.getTimeGranularity() && conditions.getTimeGranularity().equals(CtopAdConstant.BYTEDANCE_REPORT_TYPE_HOURLY)) {
-                var hourlyReport = new BytedanceAdvertiserHourlyReport(data);
+                BytedanceAdvertiserHourlyReport hourlyReport = new BytedanceAdvertiserHourlyReport(data);
                 advertiserHourlyReportService.saveOrUpdate(hourlyReport);
             } else {
-                var dailyReport = new BytedanceAdvertiserDailyReport(data);
+                BytedanceAdvertiserDailyReport dailyReport = new BytedanceAdvertiserDailyReport(data);
                 advertiserDailyReportService.saveOrUpdate(dailyReport);
             }
         }

+ 45 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/service/impl/RuleByteDanceAccountServiceImpl.java

@@ -0,0 +1,45 @@
+package cn.com.ctop.toutiao.modules.report.service.impl;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.entity.RuleDataAccount;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.service.IRuleDataAccountService;
+import cn.com.ctop.toutiao.modules.report.service.IRuleByteDanceAccountService;
+import cn.com.ctop.toutiao.modules.tool.service.IByteDanceGetAccountFundService;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RuleByteDanceAccountServiceImpl implements IRuleByteDanceAccountService {
+
+    @Autowired
+    IByteDanceGetAccountFundService byteDanceGetAccountFundService;
+    @Autowired
+    ICtopOauthTokenService oauthTokenService;
+    @Autowired
+    IRuleDataAccountService ruleDataAccountService;
+
+    @Override
+    public void cleanRuleDataAccount(Long accountId) {
+        CtopOauthToken oauthToken=oauthTokenService.getTokenByAccountId(accountId);
+        //查询账户实时数据
+        JSONObject dataAccount=byteDanceGetAccountFundService.getAccountReportBy(oauthToken,accountId);
+        if(!dataAccount.isEmpty()){
+            JSONObject fundData=byteDanceGetAccountFundService.getAccountFundBy(oauthToken,accountId);
+            RuleDataAccount ruleDataAccount=new RuleDataAccount();
+            ruleDataAccount.setId(accountId);
+            ruleDataAccount.setAccountId(accountId);
+            ruleDataAccount.setAccountName(fundData.getString("name"));
+            ruleDataAccount.setCost(dataAccount.getBigDecimal("cost"));
+            ruleDataAccount.setValidBalance(fundData.getBigDecimal("valid_balance"));
+            ruleDataAccount.setConvertNum(dataAccount.getLong("convert"));
+            ruleDataAccount.setConvertCost(dataAccount.getBigDecimal("convert_cost"));
+            ruleDataAccount.setNextDayOpenNum(dataAccount.getLong("next_day_open"));
+            ruleDataAccount.setNextDayOpenCost(dataAccount.getBigDecimal("next_day_open_cost"));
+            ruleDataAccount.setNextDayOpenCost(dataAccount.getBigDecimal("next_day_open_rate"));
+
+            ruleDataAccountService.saveOrUpdate(ruleDataAccount);
+        }
+    }
+}

+ 6 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/tool/constants/QueryToolUrlConstant.java

@@ -44,4 +44,10 @@ public class QueryToolUrlConstant {
     //获取图片素材
     public static final String FILE_IMAGE_GET="https://ad.oceanengine.com/open_api/2/file/image/get/";
 
+    //查询账户余额
+    public static final String GET_ADVERTISER_FUND="https://ad.oceanengine.com/open_api/2/advertiser/fund/get/";
+
+    //查询账户当日实时数据
+    public static final String GET_ADVERTISER_REPORT="https://ad.oceanengine.com/open_api/2/report/advertiser/get/";
+
 }

+ 23 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/tool/service/IByteDanceGetAccountFundService.java

@@ -0,0 +1,23 @@
+package cn.com.ctop.toutiao.modules.tool.service;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ *  Created by JQ.bi on 2020.11.15
+ *
+ *  拉取账户余额
+ */
+public interface IByteDanceGetAccountFundService {
+
+    /**
+     * 获取账号余额信息
+     */
+    JSONObject getAccountFundBy(CtopOauthToken token, Long advertiserId);
+
+    /**
+     * 获取账号余额信息
+     */
+    JSONObject getAccountReportBy(CtopOauthToken token, Long advertiserId);
+
+}

+ 60 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/tool/service/impl/ByteDanceGetAccountFundServiceImpl.java

@@ -0,0 +1,60 @@
+package cn.com.ctop.toutiao.modules.tool.service.impl;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.utils.HttpUtils;
+import cn.com.ctop.toutiao.modules.tool.constants.QueryToolUrlConstant;
+import cn.com.ctop.toutiao.modules.tool.service.IByteDanceGetAccountFundService;
+import com.alibaba.fastjson.JSONObject;
+import com.xxl.job.core.log.XxlJobLogger;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.constant.SystemDateConstant;
+import org.jeecg.common.util.DateUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class ByteDanceGetAccountFundServiceImpl implements IByteDanceGetAccountFundService {
+
+    @Override
+    public JSONObject getAccountFundBy(CtopOauthToken token, Long advertiserId) {
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        JSONObject params=new JSONObject();
+        params.put("advertiser_id",advertiserId);
+
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpGetRequest(QueryToolUrlConstant.GET_ADVERTISER_FUND, headers,params));
+        if(jsonObject.getInteger("code")!=0){
+            XxlJobLogger.log("查询账户余额失败==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
+            return null;
+        }
+        return jsonObject.getJSONObject("data");
+    }
+
+    @Override
+    public JSONObject getAccountReportBy(CtopOauthToken token, Long advertiserId) {
+
+        JSONObject result= new JSONObject();
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Content-Type", "application/json");
+        headers.put("Access-Token", token.getAccessToken());
+
+        String now = DateUtils.getNowDate(SystemDateConstant.yyyy_MM_dd);
+        JSONObject params=new JSONObject();
+        params.put("advertiser_id",advertiserId);
+        params.put("start_date",now);
+        params.put("end_date",now);
+        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.httpGetRequest(QueryToolUrlConstant.GET_ADVERTISER_REPORT, headers,params));
+        if(jsonObject.getInteger("code")!=0){
+            XxlJobLogger.log("账户{}获取实时数据失败---{}",advertiserId,jsonObject.getString("message"));
+        }else {
+            result= (JSONObject) jsonObject.getJSONObject("data").getJSONArray("list").get(0);
+        }
+        return result;
+    }
+}