浏览代码

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

jiequan.bi 4 年之前
父节点
当前提交
44345b6b9a

+ 10 - 0
jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java

@@ -6,6 +6,7 @@ import cn.com.ctop.common.module.entity.UserAllocation;
 import cn.com.ctop.common.module.message.handle.impl.EmailSendMsgHandle;
 import cn.com.ctop.common.module.service.*;
 import cn.com.ctop.common.module.utils.CtopAdConstant;
+import cn.com.ctop.common.module.utils.HttpUtils;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouHistoryReportTaskService;
 import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
 import cn.com.ctop.kuaishou.modules.graphql.service.IKuaishouWebInterfaceService;
@@ -116,6 +117,15 @@ public class SampleTest {
     }
 
     @Test
+    public void testXxlJobDistribute(){
+        String url = "http://127.0.0.1:8090/xxl-job-admin/jobinfo/trigger?id=88&executorParam=";
+        for(int i=0;i<100;i++){
+            String result = HttpUtils.httpPostRequest(url+i,new HashMap<>(),new HashMap<>());
+            System.out.println(result);
+        }
+    }
+
+    @Test
     public void testLoadRulePlanData(){
         Date date = new Date();
         List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();

+ 10 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/mapper/RuleAccountThresholdMapper.java

@@ -2,6 +2,7 @@ package cn.com.ctop.alarm.modules.mapper;
 
 import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -15,4 +16,13 @@ import java.util.List;
 public interface RuleAccountThresholdMapper extends BaseMapper<RuleAccountThreshold> {
 
     List<RuleAccountThreshold> selectByAccountId(Long accountId);
+
+    List<Long> selectGroupIdsByAccountId(Long accountId);
+
+    List<String> selectbatchNosByGroupIdId(Long accountId, Long groupId);
+
+    List<RuleAccountThreshold> selectCopyThresholdByAccountId(Long accountId, Long groupId, String batchNo);
+    List<String> getBatchNo(@Param("accountId") Long accountId, @Param("groupId") Long groupId);
+
+    List<RuleAccountThreshold> selectBatchNoByAccountId(Long accountId);
 }

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

@@ -5,5 +5,32 @@
     <select id="selectByAccountId" resultType="cn.com.ctop.alarm.modules.entity.RuleAccountThreshold">
        SELECT * FROM ctop_rule_account_threshold
        WHERE account_id = #{accountId}
+       AND batch_no is null
+    </select>
+    <select id="selectGroupIdsByAccountId" resultType="java.lang.Long">
+       SELECT group_id FROM `ctop_rule_account_threshold`
+        WHERE batch_no is not null
+        and  account_id = #{accountId}
+        group by group_id
+    </select>
+    <select id="selectbatchNosByGroupIdId" resultType="java.lang.String">
+       SELECT batch_no FROM `ctop_rule_account_threshold`
+        WHERE batch_no is not null
+        and account_id = #{accountId}
+        and group_id = #{groupId}
+        GROUP BY batch_no
+    </select>
+    <select id="selectCopyThresholdByAccountId" resultType="cn.com.ctop.alarm.modules.entity.RuleAccountThreshold">
+       SELECT * FROM `ctop_rule_account_threshold`
+        WHERE account_id = #{accountId}
+        and group_id = #{groupId}
+        and batch_no = #{batchNo}
+    </select>
+
+    <select id="getBatchNo" resultType="java.lang.String">
+    select   batch_no from ctop_rule_account_threshold
+    where  account_id = #{accountId}
+    and group_id = #{groupId}
+    group by batch_no
     </select>
 </mapper>

+ 4 - 0
module-alarm/src/main/java/cn/com/ctop/alarm/modules/service/IRuleAccountThresholdService.java

@@ -4,6 +4,8 @@ import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * @Description: 规则关联账户 阈值
  * @Author: jeecg-boot
@@ -19,4 +21,6 @@ public interface IRuleAccountThresholdService extends IService<RuleAccountThresh
      * @return
      */
     JSONObject fillThreshold(JSONObject requestJson) throws Exception;
+
+    List<String> getBatchNo(Long accountId, Long groupId);
 }

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

@@ -14,6 +14,7 @@ import org.springframework.stereotype.Service;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 /**
  * 规则模板
@@ -74,6 +75,12 @@ public class RuleAccountTemplateServiceImpl extends ServiceImpl<RuleAccountTempl
                 continue;
             }
             groupCount += 1;
+            Integer isCopy = ruleGroup.getIsCopy();
+            String batchId = null;
+            if (isCopy == 1) {
+                batchId = UUID.randomUUID().toString().replace("-", "");
+
+            }
             JSONArray ruleIds = JSONArray.parseArray(ruleGroup.getRuleIds());
             if (Check.isNull(ruleIds)) {
                 continue;
@@ -86,7 +93,11 @@ public class RuleAccountTemplateServiceImpl extends ServiceImpl<RuleAccountTempl
                 }
                 RuleAccountThreshold threshold = new RuleAccountThreshold();
                 threshold.setAccountId(accountId);
+                threshold.setGroupId(groupId);
                 threshold.setRuleId(ruleBase.getId());
+                if (isCopy == 1) {
+                    threshold.setBatchNo(batchId);
+                }
                 if (ruleBase.getVariableType() == 0) {
                     threshold.setThreshold(ruleBase.getThreshold());
                 }

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

@@ -8,9 +8,15 @@ 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 lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
 /**
  * 规则关联账户 阈值
  *
@@ -18,6 +24,7 @@ import org.springframework.stereotype.Service;
  * @version V1.0
  * @date 2020-11-15
  */
+@Slf4j
 @Service
 public class RuleAccountThresholdServiceImpl extends ServiceImpl<RuleAccountThresholdMapper, RuleAccountThreshold> implements IRuleAccountThresholdService {
     @Autowired
@@ -49,45 +56,88 @@ public class RuleAccountThresholdServiceImpl extends ServiceImpl<RuleAccountThre
             if (Check.isNull(ruleDetail)) {
                 continue;
             }
+            Long groupId = groupJson.getLong("groupId");
+            Integer isCopy = groupJson.getInteger("isCopy");
+            if (isCopy == 1) {
+                Map<String, Object> deleteMap = new HashMap<>();
+                deleteMap.put("account_id", accountId);
+                deleteMap.put("group_id", groupId);
+                ruleAccountThresholdMapper.deleteByMap(deleteMap); // 删除此账户下 此组绑定的失效阈值
+            }
 
             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.setThreshold(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;
+                if (isCopy == 1) { // 规则组可复制
+                    JSONArray ruleDetailArr = ruleDetail.getJSONArray(j);
+                    if (Check.isNull(ruleDetailArr)) {
+                        continue;
+                    }
+                    String batchNo = UUID.randomUUID().toString().replace("-", "");
+                    for (int k = 0; k < ruleDetailArr.size(); k++) {
+                        JSONObject ruleJson = ruleDetailArr.getJSONObject(k);
+                        if (Check.isNull(ruleJson)) {
+                            continue;
+                        }
+                        Long ruleId = ruleJson.getLong("ruleId");
+                        if (Check.isNull(ruleId)) {
+                            continue;
+                        }
+                        String threshold = ruleJson.getString("threshold");
+                        if (Check.isNull(threshold)) {
+                            continue;
+                        }
+                        RuleAccountThreshold addRuleAccountThreshold = new RuleAccountThreshold();
+                        addRuleAccountThreshold.setAccountId(accountId);
+                        addRuleAccountThreshold.setGroupId(groupId);
+                        addRuleAccountThreshold.setThreshold(threshold);
+                        addRuleAccountThreshold.setRuleId(ruleId);
+                        if (isCopy == 1) {
+                            addRuleAccountThreshold.setBatchNo(batchNo);
+                        }
+                        int insert = ruleAccountThresholdMapper.insert(addRuleAccountThreshold);
+                        if (insert > 0) {
+                            updateCount += 1;
+                        }
+                    }
+                } else if (isCopy == 0) {
+                    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();
+                    updateThreshold.setThreshold(threshold);
+                    QueryWrapper<RuleAccountThreshold> updateQueryWrapper = new QueryWrapper();
+                    updateQueryWrapper.eq("account_id", accountId);
+                    updateQueryWrapper.eq("rule_id", ruleId);
+                    updateQueryWrapper.eq("group_id", groupId);
+                    int update = ruleAccountThresholdMapper.update(updateThreshold, updateQueryWrapper);
+                    if (update > 0) {
+                        updateCount += 1;
+                    }
                 }
             }
         }
 
+        log.info("修改账户模板阈值完成,账户id:{},修改规则条数:{}", accountId, updateCount);
         JSONObject returnJson = new JSONObject();
         returnJson.put("code", 0);
         returnJson.put("updateCount", updateCount);
         return returnJson;
     }
+
+    /**
+     * 获取批次号列表
+     *
+     * @param accountId
+     * @param groupId
+     * @return
+     */
+    @Override
+    public List<String> getBatchNo(Long accountId, Long groupId) {
+        return ruleAccountThresholdMapper.getBatchNo(accountId, groupId);
+    }
 }

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

@@ -1,18 +1,8 @@
 package cn.com.ctop.alarm.modules.service.impl;
 
 import cn.com.ctop.alarm.modules.constant.MatchLogic;
-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.entity.*;
+import cn.com.ctop.alarm.modules.mapper.*;
 import cn.com.ctop.alarm.modules.service.IRuleAccountTemplateService;
 import cn.com.ctop.alarm.modules.service.IRuleGroupService;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
@@ -34,6 +24,7 @@ import org.springframework.stereotype.Service;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 /**
  * 规则组
@@ -83,7 +74,7 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
             return;
         }
         //获取规则集
-        Map<Long, List<RuleGroup>> ruleGroupMap = getRuleGroupMap();
+        Map<Long, Object> ruleGroupMap = getRuleGroupMap();
         if (Check.isNull(ruleGroupMap)) {
             log.warn("获取规则集失败");
             return;
@@ -95,36 +86,111 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
             return;
         }
         for (RuleAccountTemplate templates : ruleAccountTemplates) {
-            List<RuleGroup> ruleGroups = ruleGroupMap.get(templates.getTemplateId());
-            matchAlarmRules(ruleGroups, getThreshold(ruleAccountThresholdMapper.selectByAccountId(templates.getAccountId())), indicators, templates.getAccountId());
+            matchAlarmRules(ruleGroupMap, indicators, templates);
         }
     }
 
     /**
      * 匹配预警规则
      *
-     * @param ruleGroups   规则集
-     * @param thresholdObj 规则id阈值
-     * @param indicators   指标码
+     * @param ruleGroups 规则数据
+     * @param templates  规则模板
+     * @param indicators 指标码
      * @return void
      * @throws
      * @author ZHAOXA
      */
-    private void matchAlarmRules(List<RuleGroup> ruleGroups, JSONObject thresholdObj, JSONObject indicators, Long accountId) {
+    private void matchAlarmRules(Map<Long, Object> ruleGroupMap, JSONObject indicators, RuleAccountTemplate templates) {
         userObj = new JSONObject();
         //查询匹配数据
-        JSONObject matchData = getRuleData(accountId);
+        JSONObject matchData = getRuleData(templates.getAccountId());
         if (Check.isNull(matchData)) {
             log.warn("查询匹配数据失败");
             return;
         }
-        log.info("已获取账户({})的数据,开始匹配规则", accountId);
+        boolean isCopy = false;
+        Map<Long, Object> map = (Map<Long, Object>) ruleGroupMap.get(templates.getTemplateId());
+        //媒体类型 1:头条2:快手
+        Integer type = (Integer) map.get("type");
+        //常规规则+阈值
+        List<RuleGroup> notCopyGroups = (List<RuleGroup>) map.get("notCopy");
+        JSONObject notCopythreshold = getThreshold(templates.getAccountId(), isCopy);
+        //可复制规则+阈值
+        List<RuleGroup> isCopyGroups = (List<RuleGroup>) map.get("isCopy");
+        JSONObject isCopythreshold = new JSONObject();
+        if (!Check.isNull(isCopyGroups)) {
+            isCopy = true;
+            isCopythreshold = getThreshold(templates.getAccountId(), isCopy);
+        }
+        log.info("已获取账户({})的数据,开始匹配规则", templates.getAccountId());
         try {
-            for (RuleGroup ruleGroup : ruleGroups) {
-                List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
-                if (Check.isNull(ruleBaseList)) {
-                    continue;
+            if (!Check.isNull(notCopyGroups)) {
+                checkRuleGroups(notCopyGroups, notCopythreshold, indicators, matchData, type, false);
+            }
+            if (isCopy && !Check.isNull(isCopythreshold)) {
+                checkRuleGroups(isCopyGroups, isCopythreshold, indicators, matchData, type, isCopy);
+            }
+
+        } catch (Exception e) {
+            log.error("匹配规则逻辑异常", e);
+        }
+    }
+
+    private void checkRuleGroups(List<RuleGroup> ruleGroups, JSONObject thresholdObj, JSONObject indicators, JSONObject matchData, Integer type, boolean isCopy) {
+        for (RuleGroup ruleGroup : ruleGroups) {
+            List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
+            if (Check.isNull(ruleBaseList)) {
+                continue;
+            }
+            //复制逻辑
+            if (isCopy) {
+                JSONObject batchNo = thresholdObj.getJSONObject(ruleGroup.getId().toString());
+                for (Map.Entry<String, Object> entry : batchNo.entrySet()) {
+                    Map<String, String> thresholdMap = (Map<String, String>) entry.getValue();
+                    //符合规则的数据集
+                    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 = thresholdMap.get(ruleBase.getId());
+                        //阈值为空时,或者阈值为“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));
+                        }
+                    }
                 }
+            } else {
                 boolean isBase = "base".equals(ruleGroup.getRuleType());
                 //匹配单规则
                 if (isBase) {
@@ -151,7 +217,6 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     }
                     //匹配组合规则
                 } else {
-                    boolean flag = false;
                     //符合规则的数据集
                     JSONArray targetDatas = new JSONArray();
                     JSONArray planDatas = new JSONArray();
@@ -197,11 +262,10 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     }
                 }
             }
-        } catch (Exception e) {
-            log.error("匹配规则逻辑异常", e);
         }
     }
 
+
     /**
      * @param ruleDatas     达标数据集
      * @param dimensionData 匹配数据
@@ -310,20 +374,47 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
     }
 
     //整理阈值数据
-    public JSONObject getThreshold(List<RuleAccountThreshold> thresholdList) {
-        if (Check.isNull(thresholdList)) {
-            return null;
-        }
-        JSONObject obj = null;
+    public JSONObject getThreshold(Long accountId, boolean isCopy) {
+        JSONObject obj = new JSONObject();
         try {
-            obj = new JSONObject();
-            for (RuleAccountThreshold threshold : thresholdList) {
-                obj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
+            if (isCopy) {
+                List<Long> groupList = ruleAccountThresholdMapper.selectGroupIdsByAccountId(accountId);
+                if (Check.isNull(groupList)) {
+                    return null;
+                }
+                for (Long groupId : groupList) {
+                    JSONObject groupIdObj = new JSONObject();
+                    List<String> batchNos = ruleAccountThresholdMapper.selectbatchNosByGroupIdId(accountId, groupId);
+                    if (Check.isNull(batchNos)) {
+                        return null;
+                    }
+                    for (String batchNo : batchNos) {
+                        JSONObject batchNoObj = new JSONObject();
+                        List<RuleAccountThreshold> thresholdList = ruleAccountThresholdMapper.selectCopyThresholdByAccountId(accountId, groupId, batchNo);
+                        if (Check.isNull(thresholdList)) {
+                            return null;
+                        }
+                        for (RuleAccountThreshold threshold : thresholdList) {
+                            batchNoObj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
+                        }
+                        groupIdObj.put(batchNo.toString(), batchNoObj);
+                    }
+                    obj.put(groupId.toString(), groupIdObj);
+                }
+            } else {
+                List<RuleAccountThreshold> thresholdList = ruleAccountThresholdMapper.selectByAccountId(accountId);
+                if (Check.isNull(thresholdList)) {
+                    return null;
+                }
+                for (RuleAccountThreshold threshold : thresholdList) {
+                    obj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
+                }
             }
         } catch (Exception e) {
             log.error("获取账户阈值数据集失败", e);
         }
         return obj;
+
     }
 
     //整理指标数据
@@ -352,23 +443,36 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
      * @throws
      * @author ZHAOXA
      */
-    private Map<Long, List<RuleGroup>> getRuleGroupMap() {
+    private Map<Long, Object> getRuleGroupMap() {
         try {
-            Map<Long, List<RuleGroup>> map = new HashMap<>();
+            Map<Long, Object> returnMap = new HashMap<>();
             List<RuleTemplate> ruleTemplates = ruleTemplateMapper.selectByMap(null);
             ruleTemplates.forEach(tem -> {
+                Map<String, Object> map = new HashMap<>();
                 QueryWrapper<RuleGroup> groupWrapper = new QueryWrapper<>();
                 groupWrapper.eq("template_id", tem.getId());
-                List<RuleGroup> ruleGroups = ruleGroupMapper.selectList(groupWrapper);
-                for (RuleGroup group : ruleGroups) {
+                groupWrapper.eq("is_copy", NoEn.NO1.valueInt());
+                List<RuleGroup> copyGroups = ruleGroupMapper.selectList(groupWrapper);
+                for (RuleGroup group : copyGroups) {
                     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);
+                map.put("isCopy", copyGroups);
+                groupWrapper.eq("is_copy", NoEn.NO0.valueInt());
+                List<RuleGroup> notCopyGroups = ruleGroupMapper.selectList(groupWrapper);
+                for (RuleGroup group : notCopyGroups) {
+                    QueryWrapper<RuleBase> baseWrapper = new QueryWrapper<>();
+                    baseWrapper.eq("group_id", group.getId());
+                    baseWrapper.orderByDesc("is_unlimited");
+                    group.setRuleBaseList(ruleBaseMapper.selectList(baseWrapper));
+                }
+                map.put("notCopy", notCopyGroups);
+                map.put("type", tem.getMediaType());
+                returnMap.put(tem.getId(), map);
             });
-            return map;
+            return returnMap;
         } catch (Exception e) {
             log.error("获取模板规则组集合异常", e);
         }
@@ -428,7 +532,15 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                 if (Check.isNull(ruleDetail)) {
                     throw new Exception("规则组下指标不能为空");
                 }
+
+                Integer isCopy = groupJson.getInteger("isCopy");
+                String batchId = null;
+                if (isCopy == 1) {
+                    batchId = UUID.randomUUID().toString().replace("-", "");
+
+                }
                 JSONArray ruleIds = new JSONArray();
+                JSONArray thresholdIds = new JSONArray();
                 for (int j = 0; j < ruleDetail.size(); j++) {
                     JSONObject ruleDetailJson = ruleDetail.getJSONObject(j);
                     RuleBase ruleBase = new RuleBase();
@@ -440,7 +552,8 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                     ruleBase.setRuleDimension(ruleDetailJson.getString("ruleDimension"));
                     ruleBase.setJudgeFormat(ruleDetailJson.getInteger("judgeFormat"));
                     ruleBase.setIsUnlimited(ruleDetailJson.getInteger("isUnlimited"));
-                    int insert = ruleBaseMapper.insert(ruleBase);  // 添加基础规则
+                    int insert = ruleBaseMapper.insert(ruleBase);    // 添加基础规则
+
                     if (insert > 0) {
                         if (!Check.isNull(accountList)) {
                             for (RuleAccountTemplate accountTemplate : accountList) {
@@ -455,8 +568,14 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                                 }
                                 RuleAccountThreshold threshold = new RuleAccountThreshold();
                                 threshold.setAccountId(accountId);
+                                if (isCopy == 1) {
+                                    threshold.setBatchNo(batchId);
+                                }
                                 threshold.setRuleId(ruleBase.getId());
-                                ruleAccountThresholdMapper.insert(threshold);  // 默认将新建的规则同步到已应用的账户下
+                                int thresholdInsert = ruleAccountThresholdMapper.insert(threshold);// 默认将新建的规则同步到已应用的账户下
+                                if (thresholdInsert > 0) {
+                                    thresholdIds.add(threshold.getId());
+                                }
                             }
                         }
                         ruleIds.add(ruleBase.getId()); // 获取基本规则集
@@ -473,15 +592,21 @@ public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup
                 ruleGroup.setIsRequired(groupJson.getInteger("isRequired"));
                 boolean save = ruleGroupService.save(ruleGroup); // 新增规则组
                 if (save) {
-
                     for (int j = 0; j < ruleIds.size(); j++) {
                         Long ruleId = ruleIds.getLong(j);
                         RuleBase updateRuleBase = new RuleBase();
                         updateRuleBase.setId(ruleId);
                         updateRuleBase.setGroupId(ruleGroup.getId());
-                        ruleBaseMapper.updateById(updateRuleBase);
+                        ruleBaseMapper.updateById(updateRuleBase); // 组同步成功之后 基础规则关联到组id
                     }
+                    for (int j = 0; j < thresholdIds.size(); j++) {
+                        Long threshold = thresholdIds.getLong(j);
+                        RuleAccountThreshold updateThreshold = new RuleAccountThreshold();
+                        updateThreshold.setId(threshold);
+                        updateThreshold.setGroupId(ruleGroup.getId());
+                        ruleAccountThresholdMapper.updateById(updateThreshold); // 同步到阈值之后 阈值关联到组id
 
+                    }
                     JSONArray groupIds = JSONArray.parseArray(template.getGroupIds());
                     groupIds.add(ruleGroup.getId());
                     template.setGroupIds(groupIds.toJSONString());

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

@@ -9,9 +9,12 @@ 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 lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * 规则模板
  *
@@ -19,6 +22,7 @@ import org.springframework.stereotype.Service;
  * @version V1.0
  * @date 2020-11-15
  */
+@Slf4j
 @Service
 public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, RuleTemplate> implements IRuleTemplateService {
     @Autowired
@@ -67,9 +71,7 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
             RuleTemplate template = new RuleTemplate();
             template.setMediaType(mediaType);
             template.setTemplateName(templateName);
-
             JSONArray groupIds = new JSONArray();
-
             JSONArray ruleList = requestJson.getJSONArray("ruleList"); // 模板规则详情
             if (Check.isNull(ruleList)) {
                 throw new Exception("模板具体规则不能为空");
@@ -140,6 +142,7 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
 
                 }
             }
+            log.info("创建规则模板成功,模板名称:{}", templateName);
             returnJson.put("code", 0);
             returnJson.put("message", "创建成功");
 
@@ -266,8 +269,6 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
         if (Check.isNull(groupIds)) {
             throw new Exception("未获取规则集");
         }
-
-
         JSONArray ruleList = new JSONArray();
         for (int i = 0; i < groupIds.size(); i++) {
             Long groupId = groupIds.getLong(i);
@@ -285,68 +286,140 @@ public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, Rul
             groupJson.put("sendType", group.getSendType());
             groupJson.put("isCopy", group.getIsCopy());
             groupJson.put("isRequired", group.getIsRequired());
-            JSONArray ruleIds = JSONArray.parseArray(group.getRuleIds());
-            if (Check.isNull(ruleIds)) {
-                continue;
-            }
             JSONArray ruleDetail = new JSONArray();
-            for (int j = 0; j < ruleIds.size(); j++) {
-                Long ruleId = ruleIds.getLong(j);
-                RuleBase ruleBase = ruleBaseService.getById(ruleId);
-                if (Check.isNull(ruleBase)) {
+
+            if (group.getIsCopy() == 0) { // 规则不可复制
+                JSONArray ruleIds = JSONArray.parseArray(group.getRuleIds());
+                if (Check.isNull(ruleIds)) {
                     continue;
                 }
-                JSONObject ruleJson = new JSONObject();
-                ruleJson.put("ruleId", ruleBase.getId());
-                ruleJson.put("ruleName", ruleBase.getRuleName());
-                ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
-                ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
-                ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
-                QueryWrapper<RuleAccountThreshold> accountThresholdQueryWrapper = new QueryWrapper<>();
-                accountThresholdQueryWrapper.eq("account_id", accountId);
-                accountThresholdQueryWrapper.eq("rule_id", ruleId);
-                RuleAccountThreshold threshold = accountThresholdService.getOne(accountThresholdQueryWrapper);
-                if (!Check.isNull(threshold)) {
-                    String value = threshold.getThreshoId();
-                    if (!Check.isNull(value)) {
-                        if (value.contains("[") && value.contains("]")) {
-                            ruleJson.put("threshold", JSONArray.parseArray(value));
+                for (int j = 0; j < ruleIds.size(); j++) {
+                    Long ruleId = ruleIds.getLong(j);
+                    RuleBase ruleBase = ruleBaseService.getById(ruleId); // 查询基础规则信息
+                    if (Check.isNull(ruleBase)) {
+                        continue;
+                    }
+                    JSONObject ruleJson = new JSONObject();
+                    ruleJson.put("ruleId", ruleBase.getId());
+                    ruleJson.put("ruleName", ruleBase.getRuleName());
+                    ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
+                    ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
+                    ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
+                    QueryWrapper<RuleAccountThreshold> accountThresholdQueryWrapper = new QueryWrapper<>();
+                    accountThresholdQueryWrapper.eq("account_id", accountId);
+                    accountThresholdQueryWrapper.eq("rule_id", ruleId);
+                    accountThresholdQueryWrapper.eq("group_id", groupId);
+                    RuleAccountThreshold threshold = accountThresholdService.getOne(accountThresholdQueryWrapper); // 查询基础规则绑定的阈值
+                    if (!Check.isNull(threshold)) {
+                        String value = threshold.getThreshold();
+                        if (!Check.isNull(value)) {
+                            if (value.contains("[") && value.contains("]")) {
+                                ruleJson.put("threshold", JSONArray.parseArray(value));
+                            } else {
+                                ruleJson.put("threshold", value);
+                            }
                         } else {
-                            ruleJson.put("threshold", value);
+                            ruleJson.put("threshold", null);
                         }
-                    }else{
+                    } 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());
+                    /**
+                     * 查询指标对应信息
+                     */
+                    QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
+                    indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
+                    indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
+                    indicatorQueryWrapper.last("limit 1");
+                    RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper);  // 查询指标的详情信息
+                    if (!Check.isNull(ruleIndicator)) {
+                        ruleJson.put("dataType", ruleIndicator.getDataType());
+                        ruleJson.put("dictId", ruleIndicator.getDictId());
+                        ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
+                        ruleJson.put("name", ruleIndicator.getName());
+                        ruleJson.put("modelType", ruleIndicator.getModelType());
+                    }
+
+                    ruleDetail.add(ruleJson);
                 }
+                groupJson.put("ruleDetail", ruleDetail);
+            } else if (group.getIsCopy() == 1) {  // 如果规则可以复制
 
-                ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
-                ruleJson.put("variableType", ruleBase.getVariableType());
-                ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
-                /**
-                 * 查询指标对应信息
-                 */
-                QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
-                indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
-                indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
-                indicatorQueryWrapper.last("limit 1");
-                RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper);
-                if (!Check.isNull(ruleIndicator)) {
-                    ruleJson.put("dataType", ruleIndicator.getDataType());
-                    ruleJson.put("dictId", ruleIndicator.getDictId());
-                    ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
-                    ruleJson.put("name", ruleIndicator.getName());
-                    ruleJson.put("modelType", ruleIndicator.getModelType());
+                List<String> batchNoList = accountThresholdService.getBatchNo(accountId, groupId); // 查询批次号
+                if (Check.isNull(batchNoList)) {
+                    continue;
                 }
 
-                ruleDetail.add(ruleJson);
+
+                for (int j = 0; j < batchNoList.size(); j++) {
+                    String batchNo = (String) batchNoList.get(j);
+                    if (Check.isNull(batchNo)) {
+                        continue;
+                    }
+                    JSONArray ruleArr = new JSONArray();
+                    QueryWrapper<RuleAccountThreshold> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("account_id", accountId);
+                    queryWrapper.eq("group_id", groupId);
+                    queryWrapper.eq("batch_no", batchNo);
+                    List<RuleAccountThreshold> list = accountThresholdService.list(queryWrapper); // 根据批次号查询绑定的基础规则阈值集合
+                    if (Check.isNull(list)) {
+                        continue;
+                    }
+
+                    for (RuleAccountThreshold threshold : list) {
+                        RuleBase ruleBase = ruleBaseService.getById(threshold.getRuleId()); // 根据阈值集合ruleId 查询基础规则信息
+                        if (Check.isNull(ruleBase)) {
+                            continue;
+                        }
+                        JSONObject ruleJson = new JSONObject();
+                        ruleJson.put("ruleId", ruleBase.getId());
+                        ruleJson.put("ruleName", ruleBase.getRuleName());
+                        ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
+                        ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
+                        ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
+                        String value = threshold.getThreshold();
+                        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("ruleDimension", ruleBase.getRuleDimension());
+                        ruleJson.put("variableType", ruleBase.getVariableType());
+                        ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
+                        /**
+                         * 查询指标对应信息
+                         */
+                        QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
+                        indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
+                        indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
+                        indicatorQueryWrapper.last("limit 1");
+                        RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper); // 查询基础规则的指标信息
+                        if (!Check.isNull(ruleIndicator)) {
+                            ruleJson.put("dataType", ruleIndicator.getDataType());
+                            ruleJson.put("dictId", ruleIndicator.getDictId());
+                            ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
+                            ruleJson.put("name", ruleIndicator.getName());
+                            ruleJson.put("modelType", ruleIndicator.getModelType());
+                        }
+                        ruleArr.add(ruleJson);
+                    }
+
+                    ruleDetail.add(ruleArr);
+                }
+                groupJson.put("ruleDetail", ruleDetail);
             }
-            groupJson.put("ruleDetail", ruleDetail);
             ruleList.add(groupJson);
         }
-
         returnJson.put("ruleList", ruleList);
         return returnJson;
     }

+ 1 - 8
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/ByteDancePlanRuleDataJob.java

@@ -11,9 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 
 @Component
 public class ByteDancePlanRuleDataJob {
@@ -21,7 +18,6 @@ public class ByteDancePlanRuleDataJob {
     private ICtopOauthTokenService tokenService;
     @Autowired
     private IReportService reportService;
-    static ExecutorService executorService = Executors.newFixedThreadPool(10);
 
     @XxlJob("bytedancePlanLoadJob")
     public ReturnT<String> execute(String param) throws Exception {
@@ -30,11 +26,8 @@ public class ByteDancePlanRuleDataJob {
             Long accountId = Long.parseLong(param);
             CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
             reportService.getAdvertiserPlanRuleData(token,date,date,CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY);
-        }else{
-            List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
-            tokens.forEach(token -> executorService.submit(() -> reportService.getAdvertiserPlanRuleData(token,date,date, CtopAdConstant.BYTEDANCE_REPORT_TYPE_DAILY)));
         }
-        XxlJobLogger.log("头条全量计划数据获取完成");
+        XxlJobLogger.log("头条计划数据清洗完成:accountId=>{}",param);
         return ReturnT.SUCCESS;
     }
 }

+ 46 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceRuleDataJobDistribute.java

@@ -0,0 +1,46 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.common.module.entity.CtopOauthToken;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.utils.HttpUtils;
+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.HashMap;
+import java.util.List;
+
+@Component
+public class BytedanceRuleDataJobDistribute {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @XxlJob("bytedancePlanRuleDataJobDistribute")
+    public ReturnT<String> bytedancePlanRuleDataJobDistribute(String params) throws Exception {
+        List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+        if(null!=tokens&&!tokens.isEmpty()){
+            //TODO 指定相应的任务id
+            String planUrl = "http://139.186.29.76:8090/jobinfo/trigger?id=87&executorParam=";
+            for(CtopOauthToken token:tokens){
+                String planResult = HttpUtils.httpPostRequest(planUrl+token.getAccountId(),new HashMap<>(),new HashMap<>());
+                XxlJobLogger.log("accountId:{};message:{}",token.getAccountId(),planResult);
+            }
+        }
+        return ReturnT.SUCCESS;
+    }
+
+    @XxlJob("bytedanceAccountRuleDataJobDistribute")
+    public ReturnT<String> bytedanceAccountRuleDataJobDistribute(String params) throws Exception {
+        List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
+        if(null!=tokens&&!tokens.isEmpty()){
+            //TODO
+            String accountUrl = "http://139.186.29.76:8090/jobinfo/trigger?id=87&executorParam=";
+            for(CtopOauthToken token:tokens){
+                String accountResult = HttpUtils.httpPostRequest(accountUrl+token.getAccountId(),new HashMap<>(),new HashMap<>());
+                XxlJobLogger.log("accountId:{};message:{}",token.getAccountId(),accountResult);
+            }
+        }
+        return ReturnT.SUCCESS;
+    }
+}

+ 4 - 13
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/RuleDataAccountCleanJob.java

@@ -3,7 +3,6 @@ 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;
@@ -12,8 +11,6 @@ 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;
 
@@ -31,18 +28,12 @@ public class RuleDataAccountCleanJob {
     @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");
+        if (null == param || "".equals(param.trim())) {
+            XxlJobLogger.log("参数异常");
             return ReturnT.FAIL;
         }
-        tokens.forEach(token->executorPool.submit(() -> {
-            ruleByteDanceAccountService.cleanRuleDataAccount(token.getAccountId());
-        }));
-        if(!executorPool.isShutdown()){
-            executorPool.shutdown();
-        }
+        Long accountId = Long.parseLong(param);
+        ruleByteDanceAccountService.cleanRuleDataAccount(accountId);
         XxlJobLogger.log("规则预警账户维度数据清洗结束");
         return ReturnT.SUCCESS;
     }