|
@@ -1,22 +1,22 @@
|
|
package com.pig4cloud.pig.marketing.service.impl;
|
|
package com.pig4cloud.pig.marketing.service.impl;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.pig4cloud.pig.marketing.api.dto.MktMgmtPushRecordQueryDTO;
|
|
import com.pig4cloud.pig.marketing.api.dto.MktMgmtPushRecordQueryDTO;
|
|
import com.pig4cloud.pig.marketing.api.dto.MktMgmtPushRecordSaveDTO;
|
|
import com.pig4cloud.pig.marketing.api.dto.MktMgmtPushRecordSaveDTO;
|
|
-import com.pig4cloud.pig.marketing.api.entity.MktMgmtKeyword;
|
|
|
|
-import com.pig4cloud.pig.marketing.api.entity.MktMgmtPushRecord;
|
|
|
|
-import com.pig4cloud.pig.marketing.api.entity.MktMgmtRule;
|
|
|
|
-import com.pig4cloud.pig.marketing.api.entity.MktMgmtRuleIp;
|
|
|
|
|
|
+import com.pig4cloud.pig.marketing.api.entity.*;
|
|
import com.pig4cloud.pig.marketing.mapper.*;
|
|
import com.pig4cloud.pig.marketing.mapper.*;
|
|
import com.pig4cloud.pig.marketing.service.MktMgmtPushRecordService;
|
|
import com.pig4cloud.pig.marketing.service.MktMgmtPushRecordService;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.util.StringUtils;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
+import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author: lwh
|
|
* @author: lwh
|
|
@@ -65,180 +65,355 @@ public class MktMgmtPushRecordServiceImpl implements MktMgmtPushRecordService {
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
|
- public Boolean saveRecord(MktMgmtPushRecordSaveDTO saveDTO) {
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public String saveRecord(MktMgmtPushRecordSaveDTO saveDTO) {
|
|
log.info("新增营销推送记录,数据:{}", saveDTO);
|
|
log.info("新增营销推送记录,数据:{}", saveDTO);
|
|
|
|
|
|
try {
|
|
try {
|
|
- // 1. 根据推送内容匹配关键字
|
|
|
|
- List<MktMgmtKeyword> keywords = findMatchingKeywords(saveDTO.getPushContent());
|
|
|
|
- if (keywords.isEmpty()) {
|
|
|
|
|
|
+ // 1. 根据推送内容匹配关键字,计算每条规则的关键字匹配次数
|
|
|
|
+ Map<Long, Integer> ruleMatchCounts = calculateRuleMatchCounts(saveDTO.getPushContent());
|
|
|
|
+ if (ruleMatchCounts.isEmpty()) {
|
|
log.warn("推送内容未匹配到任何关键字:{}", saveDTO.getPushContent());
|
|
log.warn("推送内容未匹配到任何关键字:{}", saveDTO.getPushContent());
|
|
- return false;
|
|
|
|
|
|
+ return "推送内容【" + saveDTO.getPushContent() + "】未匹配到任何关键字";
|
|
}
|
|
}
|
|
|
|
|
|
- // 2. 遍历匹配的关键字,查找对应的规则
|
|
|
|
- for (MktMgmtKeyword keyword : keywords) {
|
|
|
|
- MktMgmtRule rule = mktMgmtRuleMapper.selectById(keyword.getRuleId());
|
|
|
|
- if (rule == null || "1".equals(rule.getDelFlag())) {
|
|
|
|
- log.warn("关键字对应的规则不存在或已删除,ruleId:{}", keyword.getRuleId());
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
|
|
+ // 2. 按匹配次数从高到低排序规则
|
|
|
|
+ List<Map.Entry<Long, Integer>> sortedRules = ruleMatchCounts.entrySet().stream()
|
|
|
|
+ .sorted(Map.Entry.<Long, Integer>comparingByValue().reversed())
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+
|
|
|
|
+ log.debug("按匹配次数排序的规则:{}", sortedRules);
|
|
|
|
+
|
|
|
|
+ // 3. 依次尝试每个规则,记录详细的尝试信息
|
|
|
|
+ StringBuilder errorDetails = new StringBuilder();
|
|
|
|
+ MktMgmtRule selectedRule = null;
|
|
|
|
+ Long selectedRuleId = null;
|
|
|
|
+
|
|
|
|
+ for (Map.Entry<Long, Integer> entry : sortedRules) {
|
|
|
|
+ Long ruleId = entry.getKey();
|
|
|
|
+ Integer matchCount = entry.getValue();
|
|
|
|
|
|
- // 3. 验证IP地址
|
|
|
|
- if (!validateIPAddress(rule, saveDTO.getPushIP())) {
|
|
|
|
- log.warn("IP地址验证失败,规则:{},推送IP:{}", rule.getRuleName(), saveDTO.getPushIP());
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
|
|
+ log.debug("尝试规则{},匹配次数:{}", ruleId, matchCount);
|
|
|
|
|
|
- // 4. 验证域名
|
|
|
|
- if (!validateDomain(rule, saveDTO.getPushDomain())) {
|
|
|
|
- log.warn("域名验证失败,规则:{},推送域名:{}", rule.getRuleName(), saveDTO.getPushDomain());
|
|
|
|
|
|
+ // 获取规则信息
|
|
|
|
+ MktMgmtRule rule = mktMgmtRuleMapper.selectById(ruleId);
|
|
|
|
+ if (rule == null || "1".equals(rule.getDelFlag())) {
|
|
|
|
+ log.warn("规则不存在或已删除,ruleId:{}", ruleId);
|
|
|
|
+ errorDetails.append("规则").append(ruleId).append("不存在或已删除;");
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- // 5. 构建触发条件描述
|
|
|
|
- String triggerCondition = buildTriggerCondition(keyword.getKeyword(), rule, saveDTO.getPushIP(), saveDTO.getPushDomain());
|
|
|
|
|
|
+ // 获取匹配的关键字
|
|
|
|
+ List<String> matchedKeywords = getMatchedKeywordsForRule(saveDTO.getPushContent(), ruleId);
|
|
|
|
|
|
- // 6. 构建推送详情
|
|
|
|
- String pushDetail = buildPushDetail(triggerCondition, saveDTO.getPushContent());
|
|
|
|
|
|
+ // 验证IP和域名规则
|
|
|
|
+ ValidationResult validationResult = validateRuleIpAndDomainWithDetails(ruleId, saveDTO.getPushIP(), saveDTO.getPushDomain());
|
|
|
|
|
|
- // 7. 创建推送记录
|
|
|
|
- MktMgmtPushRecord record = new MktMgmtPushRecord();
|
|
|
|
- record.setRuleName(rule.getRuleName());
|
|
|
|
- record.setPushFrequency(rule.getPushFrequency());
|
|
|
|
- record.setPushStatus(true); // 总为1-成功
|
|
|
|
- record.setTriggerCondition(triggerCondition);
|
|
|
|
- record.setPushDetail(pushDetail);
|
|
|
|
- record.setDelFlag("0"); // 未删除
|
|
|
|
-
|
|
|
|
- // 8. 保存到数据库
|
|
|
|
- int result = mktMgmtPushRecordMapper.insert(record);
|
|
|
|
- if (result > 0) {
|
|
|
|
- log.info("营销推送记录新增成功,ID:{},规则:{}", record.getId(), rule.getRuleName());
|
|
|
|
- return true;
|
|
|
|
|
|
+ if (validationResult.isValid()) {
|
|
|
|
+ selectedRule = rule;
|
|
|
|
+ selectedRuleId = ruleId;
|
|
|
|
+ log.info("找到匹配的规则:{},匹配次数:{}", rule.getRuleName(), matchCount);
|
|
|
|
+ break;
|
|
|
|
+ } else {
|
|
|
|
+ errorDetails.append("规则").append(ruleId).append("(").append(rule.getRuleName()).append(")");
|
|
|
|
+ errorDetails.append("匹配").append(matchCount).append("个关键字[").append(String.join(",", matchedKeywords)).append("]");
|
|
|
|
+ errorDetails.append("但").append(validationResult.getFailureReason()).append(";");
|
|
|
|
+ log.debug("规则{}的IP或域名验证失败:{},尝试下一个规则", ruleId, validationResult.getFailureReason());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- log.warn("未找到匹配的规则或保存失败");
|
|
|
|
- return false;
|
|
|
|
|
|
+ // 4. 如果没有找到匹配的规则
|
|
|
|
+ if (selectedRule == null) {
|
|
|
|
+ String errorMessage = "所有规则验证失败。推送内容【" + saveDTO.getPushContent() + "】,推送IP【" + saveDTO.getPushIP() + "】,推送域名【" + saveDTO.getPushDomain() + "】。" + errorDetails.toString();
|
|
|
|
+ log.warn(errorMessage);
|
|
|
|
+ return errorMessage;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 5. 获取匹配的关键字信息
|
|
|
|
+ List<String> matchedKeywords = getMatchedKeywordsForRule(saveDTO.getPushContent(), selectedRuleId);
|
|
|
|
+
|
|
|
|
+ // 6. 构建触发条件描述
|
|
|
|
+ String triggerCondition = buildTriggerCondition(matchedKeywords, selectedRule, saveDTO.getPushIP(), saveDTO.getPushDomain());
|
|
|
|
+
|
|
|
|
+ // 7. 创建推送记录
|
|
|
|
+ MktMgmtPushRecord record = getMktMgmtPushRecord(saveDTO, triggerCondition, selectedRule);
|
|
|
|
+
|
|
|
|
+ // 8. 保存到数据库
|
|
|
|
+ int result = mktMgmtPushRecordMapper.insert(record);
|
|
|
|
+ if (result > 0) {
|
|
|
|
+ log.info("营销推送记录新增成功,ID:{},规则:{},匹配关键字:{}", record.getId(), selectedRule.getRuleName(), matchedKeywords);
|
|
|
|
+ return "新增成功";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ log.warn("保存推送记录失败");
|
|
|
|
+ return "保存推送记录失败";
|
|
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
log.error("新增营销推送记录异常", e);
|
|
log.error("新增营销推送记录异常", e);
|
|
- return false;
|
|
|
|
|
|
+ return "系统异常:" + e.getMessage();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @NotNull
|
|
|
|
+ private static MktMgmtPushRecord getMktMgmtPushRecord(MktMgmtPushRecordSaveDTO saveDTO, String triggerCondition, MktMgmtRule selectedRule) {
|
|
|
|
+ String pushDetailBuilder = "\"触发条件:\" + " +
|
|
|
|
+ triggerCondition +
|
|
|
|
+ "+ \",推送内容:\" + " +
|
|
|
|
+ saveDTO.getPushContent();
|
|
|
|
+
|
|
|
|
+ // 8. 创建推送记录
|
|
|
|
+ MktMgmtPushRecord record = new MktMgmtPushRecord();
|
|
|
|
+ record.setPushContent(saveDTO.getPushContent());
|
|
|
|
+ record.setRuleName(selectedRule.getRuleName());
|
|
|
|
+ record.setPushFrequency(selectedRule.getPushFrequency());
|
|
|
|
+ record.setPushStatus(true); // 总为1-成功
|
|
|
|
+ record.setTriggerCondition(triggerCondition);
|
|
|
|
+ record.setPushDetail(pushDetailBuilder);
|
|
|
|
+ record.setDelFlag("0"); // 未删除
|
|
|
|
+ return record;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * IP地址转Long(便于比较大小)
|
|
|
|
+ */
|
|
|
|
+ private long ipToLong(String ip) {
|
|
|
|
+ String[] parts = ip.split("\\.");
|
|
|
|
+ long result = 0;
|
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
|
+ result |= Long.parseLong(parts[i]) << (24 - i * 8);
|
|
}
|
|
}
|
|
|
|
+ return result;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 根据推送内容查找匹配的关键字
|
|
|
|
|
|
+ * 计算每条规则的关键字匹配次数
|
|
|
|
+ * 逻辑:先查询每个规则的所有关键字,然后计算每个规则中有多少个关键字能匹配到推送内容
|
|
*/
|
|
*/
|
|
- private List<MktMgmtKeyword> findMatchingKeywords(String pushContent) {
|
|
|
|
|
|
+ private Map<Long, Integer> calculateRuleMatchCounts(String pushContent) {
|
|
if (!StringUtils.hasText(pushContent)) {
|
|
if (!StringUtils.hasText(pushContent)) {
|
|
- return List.of();
|
|
|
|
|
|
+ return new HashMap<>();
|
|
}
|
|
}
|
|
|
|
|
|
- // 查询所有未删除的关键字
|
|
|
|
|
|
+ // 1. 查询所有未删除的关键字,按规则ID分组
|
|
LambdaQueryWrapper<MktMgmtKeyword> queryWrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<MktMgmtKeyword> queryWrapper = new LambdaQueryWrapper<>();
|
|
queryWrapper.eq(MktMgmtKeyword::getDelFlag, "0");
|
|
queryWrapper.eq(MktMgmtKeyword::getDelFlag, "0");
|
|
List<MktMgmtKeyword> allKeywords = mktMgmtKeywordMapper.selectList(queryWrapper);
|
|
List<MktMgmtKeyword> allKeywords = mktMgmtKeywordMapper.selectList(queryWrapper);
|
|
|
|
|
|
|
|
+ // 按规则ID分组
|
|
|
|
+ Map<Long, List<MktMgmtKeyword>> keywordsByRule = allKeywords.stream()
|
|
|
|
+ .collect(Collectors.groupingBy(MktMgmtKeyword::getRuleId));
|
|
|
|
+
|
|
|
|
+ // 2. 计算每个规则的关键字匹配次数
|
|
|
|
+ Map<Long, Integer> ruleMatchCounts = new HashMap<>();
|
|
|
|
+
|
|
|
|
+ for (Map.Entry<Long, List<MktMgmtKeyword>> entry : keywordsByRule.entrySet()) {
|
|
|
|
+ Long ruleId = entry.getKey();
|
|
|
|
+ List<MktMgmtKeyword> ruleKeywords = entry.getValue();
|
|
|
|
+
|
|
|
|
+ // 计算这个规则中有多少个关键字能匹配到推送内容
|
|
|
|
+ int matchCount = 0;
|
|
|
|
+ for (MktMgmtKeyword keyword : ruleKeywords) {
|
|
|
|
+ if (pushContent.contains(keyword.getKeyword())) {
|
|
|
|
+ matchCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 只有当匹配次数大于0时才记录
|
|
|
|
+ if (matchCount > 0) {
|
|
|
|
+ ruleMatchCounts.put(ruleId, matchCount);
|
|
|
|
+ log.debug("规则{}的关键字匹配情况:总关键字数={},匹配数={}",
|
|
|
|
+ ruleId, ruleKeywords.size(), matchCount);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ log.debug("规则匹配次数统计:{}", ruleMatchCounts);
|
|
|
|
+ return ruleMatchCounts;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取指定规则匹配的关键字列表
|
|
|
|
+ */
|
|
|
|
+ private List<String> getMatchedKeywordsForRule(String pushContent, Long ruleId) {
|
|
|
|
+ if (!StringUtils.hasText(pushContent) || ruleId == null) {
|
|
|
|
+ return List.of();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询指定规则的所有关键字
|
|
|
|
+ LambdaQueryWrapper<MktMgmtKeyword> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ queryWrapper.eq(MktMgmtKeyword::getRuleId, ruleId)
|
|
|
|
+ .eq(MktMgmtKeyword::getDelFlag, "0");
|
|
|
|
+ List<MktMgmtKeyword> ruleKeywords = mktMgmtKeywordMapper.selectList(queryWrapper);
|
|
|
|
+
|
|
// 过滤匹配的关键字
|
|
// 过滤匹配的关键字
|
|
- return allKeywords.stream()
|
|
|
|
- .filter(keyword -> pushContent.contains(keyword.getKeyword()))
|
|
|
|
- .toList();
|
|
|
|
|
|
+ return ruleKeywords.stream()
|
|
|
|
+ .map(MktMgmtKeyword::getKeyword)
|
|
|
|
+ .filter(keyword -> pushContent.contains(keyword))
|
|
|
|
+ .collect(Collectors.toList());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
- * 验证IP地址
|
|
|
|
|
|
+ * 构建触发条件描述(支持多个关键字)
|
|
*/
|
|
*/
|
|
- private boolean validateIPAddress(MktMgmtRule rule, String pushIP) {
|
|
|
|
-// if (rule.getIpMode() == null || rule.getIpMode() == 0) {
|
|
|
|
-// // IP模式为0-空,不判断IP
|
|
|
|
-// return true;
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// if (!StringUtils.hasText(pushIP)) {
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// if (rule.getIpMode() == 1) {
|
|
|
|
-// // IP模式为1-单IP,判断推送IP是否为start_ip
|
|
|
|
-// return pushIP.equals(rule.getStartIp());
|
|
|
|
-// } else if (rule.getIpMode() == 2) {
|
|
|
|
-// // IP模式为2-IP段,判断推送IP是否在start_ip和end_ip之间
|
|
|
|
-// if (!StringUtils.hasText(rule.getStartIp()) || !StringUtils.hasText(rule.getEndIp())) {
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// try {
|
|
|
|
-// long pushIpLong = ipToLong(pushIP);
|
|
|
|
-// long startIpLong = ipToLong(rule.getStartIp());
|
|
|
|
-// long endIpLong = ipToLong(rule.getEndIp());
|
|
|
|
-//
|
|
|
|
-// return pushIpLong >= startIpLong && pushIpLong <= endIpLong;
|
|
|
|
-// } catch (Exception e) {
|
|
|
|
-// log.error("IP地址转换异常,pushIP:{},startIp:{},endIp:{}", pushIP, rule.getStartIp(), rule.getEndIp(), e);
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
|
|
+ private String buildTriggerCondition(List<String> keywords, MktMgmtRule rule, String pushIP, String pushDomain) {
|
|
|
|
+ StringBuilder triggerCondition = new StringBuilder();
|
|
|
|
+ triggerCondition.append("关键字:").append(String.join(",", keywords));
|
|
|
|
+
|
|
|
|
+ // 添加IP信息
|
|
|
|
+ if (StringUtils.hasText(pushIP)) {
|
|
|
|
+ triggerCondition.append(",IP:").append(pushIP);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加域名信息
|
|
|
|
+ if (StringUtils.hasText(pushDomain)) {
|
|
|
|
+ triggerCondition.append(",域名:").append(pushDomain);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return triggerCondition.toString();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 验证域名
|
|
|
|
|
|
+ * 验证结果类
|
|
*/
|
|
*/
|
|
- private boolean validateDomain(MktMgmtRule rule, String pushDomain) {
|
|
|
|
-// // 如果规则中域名为空,则不判断域名
|
|
|
|
-// if (!StringUtils.hasText(rule.getDomain())) {
|
|
|
|
-// return true;
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// // 如果推送域名为空,则验证失败
|
|
|
|
-// if (!StringUtils.hasText(pushDomain)) {
|
|
|
|
-// return false;
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// // 判断推送域名是否为规则的域名
|
|
|
|
-// return rule.getDomain().equals(pushDomain);
|
|
|
|
- return true;
|
|
|
|
|
|
+ private static class ValidationResult {
|
|
|
|
+ private final boolean valid;
|
|
|
|
+ private final String failureReason;
|
|
|
|
+
|
|
|
|
+ public ValidationResult(boolean valid, String failureReason) {
|
|
|
|
+ this.valid = valid;
|
|
|
|
+ this.failureReason = failureReason;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public boolean isValid() {
|
|
|
|
+ return valid;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getFailureReason() {
|
|
|
|
+ return failureReason;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
- * 构建触发条件描述
|
|
|
|
|
|
+ * 验证规则的IP和域名(带详细错误信息)
|
|
*/
|
|
*/
|
|
- private String buildTriggerCondition(String keyword, MktMgmtRule rule, String pushIP, String pushDomain) {
|
|
|
|
- StringBuilder triggerCondition = new StringBuilder();
|
|
|
|
- triggerCondition.append("关键字:").append(keyword);
|
|
|
|
-//
|
|
|
|
-// // 添加IP信息
|
|
|
|
-// if (rule.getIpMode() != null && rule.getIpMode() > 0 && StringUtils.hasText(pushIP)) {
|
|
|
|
-// triggerCondition.append(",IP:").append(pushIP);
|
|
|
|
-// }
|
|
|
|
-//
|
|
|
|
-// // 添加域名信息
|
|
|
|
-// if (StringUtils.hasText(rule.getDomain()) && StringUtils.hasText(pushDomain)) {
|
|
|
|
-// triggerCondition.append(",域名:").append(pushDomain);
|
|
|
|
-// }
|
|
|
|
|
|
+ private ValidationResult validateRuleIpAndDomainWithDetails(Long ruleId, String pushIP, String pushDomain) {
|
|
|
|
+ // 1. 查询规则的IP配置
|
|
|
|
+ LambdaQueryWrapper<MktMgmtRuleIp> ipQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ ipQueryWrapper.eq(MktMgmtRuleIp::getRuleId, ruleId)
|
|
|
|
+ .eq(MktMgmtRuleIp::getDelFlag, "0");
|
|
|
|
+ List<MktMgmtRuleIp> ruleIps = mktMgmtRuleIpMapper.selectList(ipQueryWrapper);
|
|
|
|
|
|
- return triggerCondition.toString();
|
|
|
|
|
|
+ // 2. 查询规则的域名配置
|
|
|
|
+ LambdaQueryWrapper<MktMgmtRuleDomain> domainQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
|
+ domainQueryWrapper.eq(MktMgmtRuleDomain::getRuleId, ruleId)
|
|
|
|
+ .eq(MktMgmtRuleDomain::getDelFlag, "0");
|
|
|
|
+ List<MktMgmtRuleDomain> ruleDomains = mktMgmtRuleDomainMapper.selectList(domainQueryWrapper);
|
|
|
|
+
|
|
|
|
+ // 3. 如果规则没有IP和域名配置,直接通过
|
|
|
|
+ if (ruleIps.isEmpty() && ruleDomains.isEmpty()) {
|
|
|
|
+ return new ValidationResult(true, null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 4. 验证IP(如果有IP配置)
|
|
|
|
+ if (!ruleIps.isEmpty()) {
|
|
|
|
+ ValidationResult ipResult = validateRuleIpsWithDetails(ruleIps, pushIP);
|
|
|
|
+ if (!ipResult.isValid()) {
|
|
|
|
+ return ipResult;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 5. 验证域名(如果有域名配置)
|
|
|
|
+ if (!ruleDomains.isEmpty()) {
|
|
|
|
+ ValidationResult domainResult = validateRuleDomainsWithDetails(ruleDomains, pushDomain);
|
|
|
|
+ if (!domainResult.isValid()) {
|
|
|
|
+ return domainResult;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return new ValidationResult(true, null);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 构建推送详情
|
|
|
|
|
|
+ * 验证规则IP列表(带详细错误信息)
|
|
*/
|
|
*/
|
|
- private String buildPushDetail(String triggerCondition, String pushContent) {
|
|
|
|
- return "触发条件:" + triggerCondition + ",推送内容:" + pushContent;
|
|
|
|
|
|
+ private ValidationResult validateRuleIpsWithDetails(List<MktMgmtRuleIp> ruleIps, String pushIP) {
|
|
|
|
+ if (!StringUtils.hasText(pushIP)) {
|
|
|
|
+ return new ValidationResult(false, "推送IP为空,但规则要求IP验证");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (MktMgmtRuleIp ruleIp : ruleIps) {
|
|
|
|
+ ValidationResult result = validateSingleRuleIpWithDetails(ruleIp, pushIP);
|
|
|
|
+ if (result.isValid()) {
|
|
|
|
+ return new ValidationResult(true, null);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return new ValidationResult(false, "推送IP " + pushIP + " 不匹配任何规则IP配置");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * IP地址转Long(便于比较大小)
|
|
|
|
|
|
+ * 验证单个规则IP(带详细错误信息)
|
|
*/
|
|
*/
|
|
- private long ipToLong(String ip) {
|
|
|
|
- String[] parts = ip.split("\\.");
|
|
|
|
- long result = 0;
|
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
|
- result |= Long.parseLong(parts[i]) << (24 - i * 8);
|
|
|
|
|
|
+ private ValidationResult validateSingleRuleIpWithDetails(MktMgmtRuleIp ruleIp, String pushIP) {
|
|
|
|
+ if (ruleIp.getIpMode() == null) {
|
|
|
|
+ return new ValidationResult(false, "规则IP配置的IP模式为空");
|
|
}
|
|
}
|
|
- return result;
|
|
|
|
|
|
+
|
|
|
|
+ if (ruleIp.getIpMode() == 1) {
|
|
|
|
+ // 单IP模式
|
|
|
|
+ if (pushIP.equals(ruleIp.getStartIp())) {
|
|
|
|
+ return new ValidationResult(true, null);
|
|
|
|
+ } else {
|
|
|
|
+ return new ValidationResult(false, "推送IP " + pushIP + " 不等于规则IP " + ruleIp.getStartIp());
|
|
|
|
+ }
|
|
|
|
+ } else if (ruleIp.getIpMode() == 2) {
|
|
|
|
+ // IP段模式
|
|
|
|
+ if (!StringUtils.hasText(ruleIp.getStartIp()) || !StringUtils.hasText(ruleIp.getEndIp())) {
|
|
|
|
+ return new ValidationResult(false, "规则IP段配置不完整,起始IP或结束IP为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ long pushIpLong = ipToLong(pushIP);
|
|
|
|
+ long startIpLong = ipToLong(ruleIp.getStartIp());
|
|
|
|
+ long endIpLong = ipToLong(ruleIp.getEndIp());
|
|
|
|
+
|
|
|
|
+ if (pushIpLong >= startIpLong && pushIpLong <= endIpLong) {
|
|
|
|
+ return new ValidationResult(true, null);
|
|
|
|
+ } else {
|
|
|
|
+ return new ValidationResult(false, "推送IP " + pushIP + " 不在IP段 " + ruleIp.getStartIp() + "-" + ruleIp.getEndIp() + " 范围内");
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ return new ValidationResult(false, "IP地址转换异常:" + e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return new ValidationResult(false, "不支持的IP模式:" + ruleIp.getIpMode());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 验证规则域名列表(带详细错误信息)
|
|
|
|
+ */
|
|
|
|
+ private ValidationResult validateRuleDomainsWithDetails(List<MktMgmtRuleDomain> ruleDomains, String pushDomain) {
|
|
|
|
+ if (!StringUtils.hasText(pushDomain)) {
|
|
|
|
+ return new ValidationResult(false, "推送域名为空,但规则要求域名验证");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (MktMgmtRuleDomain ruleDomain : ruleDomains) {
|
|
|
|
+ if (pushDomain.equals(ruleDomain.getDomain())) {
|
|
|
|
+ return new ValidationResult(true, null);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String configuredDomains = ruleDomains.stream()
|
|
|
|
+ .map(MktMgmtRuleDomain::getDomain)
|
|
|
|
+ .collect(Collectors.joining(", "));
|
|
|
|
+
|
|
|
|
+ return new ValidationResult(false, "推送域名 " + pushDomain + " 不匹配任何规则域名配置:" + configuredDomains);
|
|
}
|
|
}
|
|
}
|
|
}
|